
	/*
	** This program parses an EMA response CSV file
	** to create a PhoneView -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).
	**
	** The time of each activity is taken from field U and X-AA that 
	** were manually reported and converted by Stef to 24-hour time.
	** Field U is lapse meal time, field V is a lapse-type identifier.
	** Fields X-AA are up to four times of planned meals (can be blank).
	** The date of each activity is taken from field M which is the
	** initiation of the EMA.  If that field does not have a date then
	** it is taken from field L which is the completion time of the
	** EMA by the subject.
	**
	*/

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

#define	DEBUG		0
#define	MAX_EMA		500
#define	MAX_MEALS	20
#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	TotalEMA,ValidEMA;
char	text[320],byte;
char	ema_timestamp[MAX_EMA][32];
char	ema_lapse[MAX_EMA][32];
char	ema_lapse_type[MAX_EMA][32];
char	ema_meal[MAX_EMA][4][32];
int	year,month,day;
int	ema_year,ema_month,ema_day;
char	meal_name[MAX_MEALS][80];
char	meal_start[MAX_MEALS][32],meal_end[MAX_MEALS][32];
int	meal_unixtime[MAX_EMA];
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:  parse-ema [ema.csv] [YYYY-MM-DD.act]\n");
  exit(0);
  }

strcpy(text,argv[2]);
i=strlen(text);
text[i-4]=text[i-7]=text[i-10]=0;
year=atoi(&(text[i-14]))+1;
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;
TotalEMA=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 (strcmp(text,"Compliance") == 0  ||  strlen(text) == 0)
        ValidEMA=0;	/* last 2 lines of file */
      else
        ValidEMA=1;
      ema_year=ema_month=ema_day=0;
      }
    if (field == 11)	/* EMA response day/time */
      {
      if (strlen(text) > 1)
        {
        strcpy(ema_timestamp[TotalEMA],text);
        text[4]=text[7]=text[10]=0;
        ema_year=atoi(&(text[0]));
        ema_month=atoi(&(text[5]));
        ema_day=atoi(&(text[8]));
        }
      }
    if (field == 12)	/* EMA request day/time - if present use this */
      {
      if (strlen(text) > 1)
        {
        strcpy(ema_timestamp[TotalEMA],text);
        text[4]=text[7]=text[10]=0;
        ema_year=atoi(&(text[0]));
        ema_month=atoi(&(text[5]));
        ema_day=atoi(&(text[8]));
        }
      }
    if (field == 20)
      strcpy(ema_lapse[TotalEMA],text);
    if (field == 21)
      strcpy(ema_lapse_type[TotalEMA],text);
    if (field == 23)
      strcpy(ema_meal[TotalEMA][0],text);
    if (field == 24)
      strcpy(ema_meal[TotalEMA][1],text);
    if (field == 25)
      strcpy(ema_meal[TotalEMA][2],text);
    if (field == 26)
      strcpy(ema_meal[TotalEMA][3],text);
    field++;
    length=0;
    if (i == 0)
      break;
    if (byte == '\n')
      {
      if (ema_year != year  ||  ema_month != month  ||  ema_day != day)
        ValidEMA=0;
      if (ValidEMA)
        {
        TotalEMA++;
        }
      field=0;
      }
    continue;
    }
  text[length]=byte;
  length++;
  }
fclose(fpt);


	/* convert EMA to meals */
TotalMeals=0;
for (i=0; i<TotalEMA; i++)
  {
  if (strlen(ema_lapse[i]) > 0)
    {
    strcpy(meal_name[TotalMeals],"lapse");
    strcpy(meal_start[TotalMeals],ema_lapse[i]);
    strcpy(meal_end[TotalMeals],ema_lapse[i]);
    meal_end[TotalMeals][strlen(ema_lapse[i])-1]='1';
    TotalMeals++;
    }
  for (j=0; j<4; j++)
    {
    if (strlen(ema_meal[i][j]) > 0)
      {
      strcpy(meal_name[TotalMeals],"planned");
      strcpy(meal_start[TotalMeals],ema_meal[i][j]);
      strcpy(meal_end[TotalMeals],ema_meal[i][j]);
      meal_end[TotalMeals][strlen(ema_meal[i][j])-1]='1';
      TotalMeals++;
      }
    }
  }

	/* convert meal date/time to unix timestamps */
for (i=0; i<TotalMeals; i++)
  {
  strcpy(text,meal_start[i]);
  cyear=0;
  cmonth=1;
  cday=1;
  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);
  }

if (0)	/* print out all EMAs */
for (i=0; i<TotalEMA; i++)
  {
  j=0;
  while (j < strlen(ema_timestamp[i])  &&  ema_timestamp[i][j] != ' ')
    j++;
  ema_timestamp[i][j]=0;
  printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
	ema_timestamp[i],&(ema_timestamp[i][j+1]),
	ema_lapse[i],ema_lapse_type[i],
	ema_meal[i][0],ema_meal[i][1],ema_meal[i][2],ema_meal[i][3]);
  }
}
	






	/* 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);
}






