
	/*
	** This program parses an EMA response CSV file
	** and a results-spans.txt file from PhoneView.
	** It correlates them to create two types of output:
	**
	** per day:
	** (1) PID (participant ID)
	** (2) date
	** (3) EMA (qty of EMAs, from 0 to N)
	** (4) wrist motion active (%time moving)
	** (5) wrist at rest (%time on but not moving)
	** (6) lapse meals reported in EMA (from 0 to N)
	** (7) planned meals reported in EMA (from 0 to N)
	** (8) wrist meals detected (from 0 to N)
	**
	** per meal:
	** (1) PID (participant ID)
	** (2) date
	** (3) start time (wrist end time is unused here)
	** (4) meal type (wrist, planned, lapse)
	** (5) delta match (hr from closest wrist to this planned/lapse)
	** (6) bites
	** (7) duration (sec)
	** (8) eating rate (sec per bite)
	** (9) survey ID (EMA identifier used to report planned/lapse)
	** (10) EMA delta (hr from most recent EMA to this wrist)
	**
	** Fields (5-9) are only applicable to EMA meals; for wrist the
	** output is NA.
	** Field 10 is only applicable to wrist meals; for EMA meals
	** the output is NA.
	**
	** Delta match time is the nearest wrist detection to this EMA
	** response; can be positive or negative (printing in hours,
	** storing in program in sec).
	** EMA time delta (time to next EMA response) is the time between
	** when a wrist detection occurred and the next EMA response;
	** it can only be positive (printing in hours, storing in sec).
	**
	** The date range to be processed is the union of all dates
	** covered in both the EMA and EatMon files.
	**
	** See ema-to-events.c for more details on how EMA data is
	** converted into meal-level data.
	**
	** Wrist motion data is filename, start, end, class,
	** where class {0,1,2,3}={eating,other,rest,walking},
	** bites, duration, spb.
	*/

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

#define	DEBUG		0
#define	MAX_EMA		1000
#define	MAX_MEALS	10000
#define	MAX_SPANS	20000
#define	MAX_CALENDAR	365	/* units are days */
#define	DELTA_W		7200	/* units are seconds */
#define	SEPARATOR	','

#define	SWAP_INT(x,y)	{ swap_int=x; x=y; y=swap_int; }
#define	SWAP_DOUBLE(x,y) { swap_double=x; x=y; y=swap_double; }
#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,k,field,length;
int		a,b,c,d,e,subID;
int		TotalEMA,ValidEMA;
char		text[320],byte;
int		ema_year,ema_month,ema_day;
int		ema_hour,ema_minute,ema_second;
int		ema_timestamp[MAX_EMA];
int		smallest;
char		swap_str[320];
int		swap_int;
double		swap_double;
int		meal_year,meal_month,meal_day;
int		meal_hour,meal_minute,meal_second;
int		meal_timestamp[MAX_MEALS];
char		meal_name[MAX_MEALS][80];
int		meal_surv_num[MAX_MEALS],SurveyNumber;
int		TotalMeals;
int             meal_bites[MAX_MEALS];     /* only applic for wrist meals */
double          meal_duration[MAX_MEALS];  /* only applic for wrist meals */
double          meal_spb[MAX_MEALS];       /* only applic for wrist meals */

char            s_filename[320],s_start[32],s_end[32];
unsigned char   cyear,cmonth,cday,chour,cminute,csecond;
int		eyear,emonth,eday,ehour,eminute,esecond;
int		iyear,imonth,iday,ihour,iminute,isecond;
int             TotalSpans;
int             *span_class;
int             *span_start_ts;
int             *span_end_ts;
int             *span_bites;       /* only applic if class = 0 */
double          *span_duration;  /* only applic if class = 0 */
double          *span_spb;         /* only applic if class = 0 */

int             meal_delta_match[MAX_MEALS];    /* units are sec */
int		meal_has_been_matched[MAX_MEALS]; /* index of match */
int		closest_index,closest_delta,delta;
int		meal_ema_match[MAX_MEALS];	/* units are sec */

int             TotalCalendarDays,calendar_start,calendar_end;
int             calendar_timestamp[MAX_CALENDAR];
int             calendar_ema[MAX_CALENDAR];
int             calendar_wrist_active[MAX_CALENDAR];
int             calendar_wrist_rest[MAX_CALENDAR];
int             calendar_meal_ema_lapse[MAX_CALENDAR];
int             calendar_meal_ema_planned[MAX_CALENDAR];
int             calendar_meal_ema_both[MAX_CALENDAR];
int             calendar_meal_wrist[MAX_CALENDAR];



if (argc != 4)
  {
  printf("Usage:  parse-ema [subID] [ema.csv] [wrist.txt]\n");
  exit(0);
  }

subID=atoi(argv[1]);
if (subID < 101  ||  subID > 141)
  {
  printf("Expected subject ID >= 101 and <= 141\n");
  exit(0);
  }


	/* read the EMA file */
if ((fpt=fopen(argv[2],"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 (atoi(text) > 0)	/* survey number */
        {
        ValidEMA=1;
	SurveyNumber=atoi(text);
	}
      else
        ValidEMA=0;
      }
    if (field == 1)
      {
      if (atoi(text) != subID)
	ValidEMA=0;	/* wrong person */
      }
    if (ValidEMA == 1  &&  field == 9)	/* EMA session end day/time */
      {
      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++;
        e=d+1;
        while (text[e] != ':'  &&  text[e] != 0)
          e++;
        text[a]=text[b]=text[c]=text[d]=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]));
        ema_second=atoi(&(text[e+1]));
		/* convert date to unix-timestamps */
        ema_timestamp[TotalEMA]=TimeStamp((unsigned char)(ema_year-2000),
		(unsigned char)(ema_month),
		(unsigned char)(ema_day),
		(unsigned char)ema_hour,
		(unsigned char)ema_minute,
		(unsigned char)ema_second);
	TotalEMA++;
        if (TotalEMA >= MAX_EMA)
	  {
	  printf("MAX_EMA (%d) exceeded\n",MAX_EMA);
	  exit(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;
        meal_month=atoi(&(text[0]));
        meal_day=atoi(&(text[a+1]));
        meal_year=atoi(&(text[b+1]));
        meal_hour=atoi(&(text[c+1]));
        meal_minute=atoi(&(text[d+1]));
	meal_second=0;
        if (field == 13)
          strcpy(meal_name[TotalMeals],"lapse");
        else
          strcpy(meal_name[TotalMeals],"planned");
		/* convert date to unix-timestamps */
        meal_timestamp[TotalMeals]=TimeStamp((unsigned char)(meal_year-2000),
		(unsigned char)(meal_month),
		(unsigned char)(meal_day),
		(unsigned char)meal_hour,
		(unsigned char)meal_minute,
		(unsigned char)meal_second);
	meal_surv_num[TotalMeals]=SurveyNumber;
        meal_delta_match[TotalMeals]=0;
        meal_bites[TotalMeals]=0;
        meal_duration[TotalMeals]=0.0;
        meal_spb[TotalMeals]=0.0;
        TotalMeals++;
        }
      }
    field++;
    length=0;
    if (i == 0)
      break;
    if (byte == '\n')
      {
      if (ValidEMA)
        {
        }
      field=0;
      }
    continue;
    }
  text[length]=byte;
  length++;
  }
fclose(fpt);


        /* sort EMA timestamps */
for (i=0; i<TotalEMA; i++)
  {
  smallest=i;
  for (j=i+1; j<TotalEMA; j++)
    if (ema_timestamp[j] < ema_timestamp[smallest])
      smallest=j;
  if (smallest != i)
    {
    SWAP_INT(ema_timestamp[i],ema_timestamp[smallest]);
    }
  }


if (0)	/* print out all EMAs */
for (i=0; i<TotalEMA; i++)
  {
  DateFromTimestamp(ema_timestamp[i],&ema_year,&ema_month,&ema_day,
	&ema_hour,&ema_minute,&ema_second);
  printf("%d-%d-%d\t%d\n",
	ema_year+2000,ema_month+1,ema_day+1,
	ema_timestamp[i]);
  }

        /* sort meal timestamps */
if (0)
for (i=0; i<TotalMeals; i++)
  {
  smallest=i;
  for (j=i+1; j<TotalMeals; j++)
    if (meal_timestamp[j] < meal_timestamp[smallest])
      smallest=j;
  if (smallest != i)
    {
    SWAP_INT(meal_timestamp[i],meal_timestamp[smallest]);
    SWAP_INT(meal_surv_num[i],meal_surv_num[smallest]);
    SWAP_STR(meal_name[i],meal_name[smallest]);
    }
  }

if (0)	/* print out all EMA meals */
for (i=0; i<TotalMeals; i++)
  {
  DateFromTimestamp(meal_timestamp[i],&meal_year,&meal_month,&meal_day,
	&meal_hour,&meal_minute,&meal_second);
  printf("%d-%d-%d\t%d\t%d\t%s\n",
	meal_year+2000,meal_month+1,meal_day+1,
	meal_timestamp[i],meal_surv_num[i],meal_name[i]);
  }



        /* allocate memory for spans */
span_class=(int *)calloc(MAX_SPANS,sizeof(int));
span_start_ts=(int *)calloc(MAX_SPANS,sizeof(int));
span_end_ts=(int *)calloc(MAX_SPANS,sizeof(int));
span_bites=(int *)calloc(MAX_SPANS,sizeof(int));
span_duration=(double *)calloc(MAX_SPANS,sizeof(double));
span_spb=(double *)calloc(MAX_SPANS,sizeof(double));

	/* read the results-spans text file */
if ((fpt=fopen(argv[3],"r")) == NULL)
  {
  printf("Unable to open %s for reading\n",argv[2]);
  exit(0);
  }
TotalSpans=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 (field == 0)
      strcpy(s_filename,text);
    if (field == 1)
      strcpy(s_start,text);
    if (field == 2)
      strcpy(s_end,text);
    if (field == 3)
      span_class[TotalSpans]=atoi(text);
    if (field == 4)
      span_bites[TotalSpans]=atoi(text);
    if (field == 5)
      span_duration[TotalSpans]=atof(text);
    if (field == 6)
      span_spb[TotalSpans]=atof(text);
    field++;
    length=0;
    if (i == 0)
      break;
    if (byte == '\n')
      {
	/* check if this is desired subject */
	/* filename assumed to be ......\subID\download\year-mon-day.act */
      a=strlen(s_filename)-1;
      for (b=0; b<3; b++)
        {
        while (s_filename[a] != '\\'  &&  s_filename[a] != '/'  &&  a > 0)
          a--;
        a--;
	}
      strncpy(text,&(s_filename[a+2]),3);
      text[3]=0;
      if (atoi(text) == subID)
	{
	/* convert date/time to unix-timestamps */
        strcpy(text,s_filename);
        e=strlen(text);
        text[e-4]=text[e-7]=text[e-10]=text[e-15]=0;
        cyear=(unsigned char)atoi(&(text[e-13]));	/* clip the millenium */
        cmonth=(unsigned char)atoi(&(text[e-9]));
        cday=(unsigned char)atoi(&(text[e-6]));
        strcpy(text,s_start);
        text[2]=0;
        chour=(unsigned char)atoi(&(text[0]));
        cminute=(unsigned char)atoi(&(text[3]));
        csecond=0;
        span_start_ts[TotalSpans]=TimeStamp(cyear,cmonth,cday,
		chour,cminute,csecond);
        strcpy(text,s_end);
        text[2]=0;
        chour=(unsigned char)atoi(&(text[0]));
        cminute=(unsigned char)atoi(&(text[3]));
        csecond=0;
        span_end_ts[TotalSpans]=TimeStamp(cyear,cmonth,cday,
		chour,cminute,csecond);
        if (0)
          printf("%d => %s %s %d %d %d\n",TotalSpans,s_start,s_end,
		span_class[TotalSpans],
		span_start_ts[TotalSpans],span_end_ts[TotalSpans]);

        TotalSpans++;
        if (TotalSpans >= MAX_SPANS)
	  {
	  printf("MAX_SPANS (%d) exceeded\n",MAX_SPANS);
	  exit(0);
	  }
	}

	/* reset counters for next line */
      field=0;
      }
    continue;
    }
  text[length]=byte;
  length++;
  }
fclose(fpt);



	/* sort spans by unix timestamps */
for (i=0; i<TotalSpans; i++)
  {
  smallest=i;
  for (j=i+1; j<TotalSpans; j++)
    if (span_start_ts[j] < span_start_ts[smallest])
      smallest=j;
  if (smallest != i)
    {
    SWAP_INT(span_start_ts[i],span_start_ts[smallest]);
    SWAP_INT(span_end_ts[i],span_end_ts[smallest]);
    SWAP_INT(span_class[i],span_class[smallest]);
    SWAP_INT(span_bites[i],span_bites[smallest]);
    SWAP_DOUBLE(span_duration[i],span_duration[smallest]);
    SWAP_DOUBLE(span_spb[i],span_spb[smallest]);
    }
  }


	/* parse meals from wrist motion data */
for (i=0; i<TotalSpans; i++)
  {
  if (span_class[i] == 0)	/* eating class is 0 */
    {
    strcpy(meal_name[TotalMeals],"wrist");
    meal_timestamp[TotalMeals]=span_start_ts[i];	/* ignoring end */
    meal_delta_match[TotalMeals]=0;
    meal_bites[TotalMeals]=span_bites[i];
    meal_duration[TotalMeals]=span_duration[i];
    meal_spb[TotalMeals]=span_spb[i];
    meal_surv_num[TotalMeals]=0;
    TotalMeals++;
    if (TotalMeals >= MAX_MEALS)
      {
      printf("MAX_MEALS (%d) exceeded\n",MAX_MEALS);
      exit(0);
      }
    }
  }



	/* sort meals by unix timestamps */
for (i=0; i<TotalMeals; i++)
  {
  smallest=i;
  for (j=i+1; j<TotalMeals; j++)
    if (meal_timestamp[j] < meal_timestamp[smallest])
      smallest=j;
  if (smallest != i)
    {
    SWAP_STR(meal_name[i],meal_name[smallest]);
    SWAP_INT(meal_timestamp[i],meal_timestamp[smallest]);
    SWAP_INT(meal_delta_match[i],meal_delta_match[smallest]);
    SWAP_INT(meal_bites[i],meal_bites[smallest]);
    SWAP_DOUBLE(meal_duration[i],meal_duration[smallest]);
    SWAP_DOUBLE(meal_spb[i],meal_spb[smallest]);
    SWAP_INT(meal_surv_num[i],meal_surv_num[smallest]);
    }
  }




	/* calcualte time-delta for each EMA meal to closest wrist meal */
for (i=0; i<TotalMeals; i++)
  meal_has_been_matched[i]=-1;	/* not matched */
	/* two passes -- lapses (or both) first, as they are most important */
for (i=0; i<TotalMeals; i++)
  {
  if (strcmp(meal_name[i],"lapse") != 0)
    continue;
  closest_delta=9999999;
  closest_index=-1;
  for (j=0; j<TotalMeals; j++)
    {
    if (i == j)
      continue;
    if (strcmp(meal_name[j],"wrist") != 0)
      continue;
    if (meal_has_been_matched[j] != -1)
      continue;
    delta=meal_timestamp[j]-meal_timestamp[i];
    if (abs(delta) < abs(closest_delta))
      {
      closest_delta=delta;
      closest_index=j;
      }
    }
  if (closest_index != -1)
    {
    meal_delta_match[i]=closest_delta;
    meal_has_been_matched[closest_index]=i;	/* wrist pointing to EMA */
    meal_has_been_matched[i]=closest_index;	/* EMA pointing to wrist */
    }
  }
	/* second pass -- match other EMAs (planned) */
for (i=0; i<TotalMeals; i++)
  {
  if (strcmp(meal_name[i],"planned") != 0)
    continue;
  closest_delta=9999999;
  closest_index=-1;
  for (j=0; j<TotalMeals; j++)
    {
    if (i == j)
      continue;
    if (strcmp(meal_name[j],"wrist") != 0)
      continue;
    if (meal_has_been_matched[j] != -1)
      continue;
    delta=meal_timestamp[j]-meal_timestamp[i];
    if (abs(delta) < abs(closest_delta))
      {
      closest_delta=delta;
      closest_index=j;
      }
    }
  if (closest_index != -1)
    {
    meal_delta_match[i]=closest_delta;
    meal_has_been_matched[closest_index]=i;	/* wrist pointing to EMA */
    meal_has_been_matched[i]=closest_index;	/* EMA pointing to wrist */
    }
  }




	/* calcualte time-delta for each wrist meal to the next EMA response */
for (i=0; i<TotalMeals; i++)
  {
  if (strcmp(meal_name[i],"wrist") != 0)
    continue;
  closest_delta=9999999;
  closest_index=-1;
  for (j=0; j<TotalEMA; j++)
    {
    delta=ema_timestamp[j]-meal_timestamp[i];
    if (delta > 0  &&  (closest_index == -1  ||  delta < closest_delta))
      {
      closest_delta=delta;
      closest_index=j;
      }
    }
  if (closest_index != -1)
    meal_ema_match[i]=closest_delta;	/* units are sec */
  else
    meal_ema_match[i]=-1;	/* no EMA after this wrist detection */
  }




	/* calculate union of date range for EMA and wrist data */
if (span_start_ts[0] < ema_timestamp[0])
  calendar_start=span_start_ts[0];
else
  calendar_start=ema_timestamp[0];
if (span_start_ts[TotalSpans-1] > ema_timestamp[TotalEMA-1])
  calendar_end=span_start_ts[TotalSpans-1];
else
  calendar_end=ema_timestamp[TotalEMA-1];
	/* round calendar end to 23:59:59 so we get the whole day */
DateFromTimestamp(calendar_end,&iyear,&imonth,&iday,&ihour,&iminute,&isecond);
calendar_end=TimeStamp((unsigned char)iyear,(unsigned char)(imonth+1),
	(unsigned char)(iday+1),(unsigned char)(23),
	(unsigned char)(59),(unsigned char)(59));
	/* increment through entire calendar range to calculate daily stats */
TotalCalendarDays=0;
calendar_timestamp[0]=calendar_start;
while (calendar_timestamp[TotalCalendarDays] < calendar_end)
  {
  calendar_ema[TotalCalendarDays]=0;
  DateFromTimestamp(calendar_timestamp[TotalCalendarDays],
	&iyear,&imonth,&iday,&ihour,&iminute,&isecond);
  for (i=0; i<TotalEMA; i++)
    {
    DateFromTimestamp(ema_timestamp[i],
	&eyear,&emonth,&eday,&ehour,&eminute,&esecond);
    if (eyear == iyear  &&  emonth == imonth  &&  eday == iday)
      calendar_ema[TotalCalendarDays]++;
    }
	/* calculate #seconds of day that device was active/rest */
  calendar_wrist_active[TotalCalendarDays]=0;
  calendar_wrist_rest[TotalCalendarDays]=0;
  for (i=0; i<TotalSpans; i++)
    {
    DateFromTimestamp(span_start_ts[i],
	&eyear,&emonth,&eday,&ehour,&eminute,&esecond);
    if (eyear == iyear  &&  emonth == imonth  &&  eday == iday)
      {
      if (span_class[i] == 2)	/* rest class is 2 */
        calendar_wrist_rest[TotalCalendarDays]+=
		(span_end_ts[i]-span_start_ts[i]);
      else
        calendar_wrist_active[TotalCalendarDays]+=
		(span_end_ts[i]-span_start_ts[i]);
      }
    }
	/* calculate #meals (both EMA and wrist) for the day */
  calendar_meal_ema_lapse[TotalCalendarDays]=0;
  calendar_meal_ema_planned[TotalCalendarDays]=0;
  calendar_meal_wrist[TotalCalendarDays]=0;
  for (i=0; i<TotalMeals; i++)
    {
    DateFromTimestamp(meal_timestamp[i],
	&meal_year,&meal_month,&meal_day,
	&meal_hour,&meal_minute,&meal_second);
if (0)
printf("looking for %d-%d-%d testing %d-%d-%d\n",iyear,imonth+1,iday+1,
	meal_year,meal_month+1,meal_day+1);
	/* must increment imonth and iday by 1 because they range 0...N-1 */
    if (meal_year == iyear  &&  meal_month == imonth  &&
	meal_day == iday)
      {
      if (strcmp(meal_name[i],"wrist") == 0)
        calendar_meal_wrist[TotalCalendarDays]++;
      else if (strcmp(meal_name[i],"lapse") == 0)
        calendar_meal_ema_lapse[TotalCalendarDays]++;
      else if (strcmp(meal_name[i],"planned") == 0)
        calendar_meal_ema_planned[TotalCalendarDays]++;
      }
    }
  TotalCalendarDays++;
  calendar_timestamp[TotalCalendarDays]=
		calendar_timestamp[TotalCalendarDays-1]+86400;
  }


if (1)	/* print out calendar */
  {
  printf("PID%cdate%cEMA%cw_actv%cw_rest%cl_meal%cp_meal%cw_meal\n",
	SEPARATOR,SEPARATOR,SEPARATOR,SEPARATOR,SEPARATOR,
	SEPARATOR,SEPARATOR,SEPARATOR);
  for (i=0; i<TotalCalendarDays; i++)
    {
    DateFromTimestamp(calendar_timestamp[i],
	&iyear,&imonth,&iday,&ihour,&iminute,&isecond);
    printf("%d%c%d-%d-%d%c%d%c%.2lf%c%.2lf%c%d%c%d%c%d\n",
	subID,SEPARATOR,
	iyear+2000,imonth+1,iday+1,SEPARATOR,
	calendar_ema[i],SEPARATOR,
	(double)(calendar_wrist_active[i])/86400.0,SEPARATOR,
	(double)(calendar_wrist_rest[i])/86400.0,SEPARATOR,
	calendar_meal_ema_lapse[i],SEPARATOR,
	calendar_meal_ema_planned[i],SEPARATOR,
	calendar_meal_wrist[i]);
    }
  }
  



if (1)  /* print out all meals */
  {
  printf("PID%cdate%cstart%ctype%cw_match%cbites%cdur%cspb%csurvey%ce_match\n",
        SEPARATOR,
	SEPARATOR,SEPARATOR,SEPARATOR,
        SEPARATOR,SEPARATOR,
        SEPARATOR,SEPARATOR,SEPARATOR);
  for (i=0; i<TotalMeals; i++)
    {
    printf("%d%c",subID,SEPARATOR);
    DateFromTimestamp(meal_timestamp[i],
	&meal_year,&meal_month,&meal_day,
	&meal_hour,&meal_minute,&meal_second);
	meal_year+=2000;	/* add millenial */
	meal_month+=1;		/* convert 0-11 to 1-12 */
	meal_day+=1;		/* conver 0-x to 1-(x+1) */
    printf("%d-%d-%d%c%02d:%02d%c%s",
        meal_year,meal_month,meal_day,SEPARATOR,
        meal_hour,meal_minute,SEPARATOR,
        meal_name[i]);
    if (strcmp(meal_name[i],"wrist") != 0)
      printf("%c%.1lf",
        SEPARATOR,(double)(meal_delta_match[i])/3600.0);
    else
      printf("%cNA",SEPARATOR);
    if (strcmp(meal_name[i],"wrist") == 0)
      printf("%c%d%c%.1lf%c%.1lf",
        SEPARATOR,meal_bites[i],
        SEPARATOR,meal_duration[i],
        SEPARATOR,meal_spb[i]);
    else
      printf("%c%d%c%.1lf%c%.1lf",
        SEPARATOR,meal_bites[meal_has_been_matched[i]],
        SEPARATOR,meal_duration[meal_has_been_matched[i]],
        SEPARATOR,meal_spb[meal_has_been_matched[i]]);
    if (strcmp(meal_name[i],"wrist") == 0)
      printf("%cNA",SEPARATOR);
    else
      printf("%c%d",SEPARATOR,meal_surv_num[i]);
    if (strcmp(meal_name[i],"wrist") != 0)
      printf("%cNA\n",SEPARATOR);
    else
      printf("%c%.1lf\n",SEPARATOR,(double)(meal_ema_match[i])/3600.0);
    }

  }

}
	






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
















