
#define _CRT_SECURE_NO_WARNINGS	  /* disable compiler warnings for standard C functions like strcpy() */

#define SQR(x)	((x)*(x))

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <windows.h>
#include <winuser.h>

#include "globals.h"
#include "resource.h"

void PaintImage()

{
PAINTSTRUCT			Painter;
HDC					hDC;
SCROLLINFO			bar_pos;
BITMAPINFOHEADER	bm_info_header;
BITMAPINFO			bm_info;
char				textout[320];
RECT				rect,fillrect;
int					x,y,d,p,j;
POINT				linearray[2];
HBRUSH				brush;
char				text[320];
int					midline[7];
int					d_left,d_right,g;
int					IBI;
double				IBI_average,IBI_stddev;
long				temp_swap;
int					i,BitesPerMin[MAX_DATA/(15*10)],CyclesPerMin[MAX_DATA/(15*10)]; /* measure once per 10 sec */
double				CyclesPerMinRatio[MAX_DATA/(15*10)];	/* CPM/CPM(avg) */
double				BPM_average,BPM_stddev,CPM_average,CPM_stddev,covar;
int					r,c;

if (DataLoaded)
  {
  hDC=GetDC(MainWnd);
		  /* set horizontal scroll bar */
  GetClientRect(MainWnd,&rect);
  rect.left+=DISPLAY_COLS;
  DataDisplayWidth=rect.right-rect.left;
  bar_pos.cbSize=sizeof(SCROLLINFO);
  bar_pos.fMask=SIF_ALL;
  bar_pos.nMin=0; 
  bar_pos.nMax=TotalData-1+DataDisplayWidth-1;
  bar_pos.nPage=DataDisplayWidth;
  bar_pos.nPos=TimeIndex;
  SetScrollInfo(MainWnd,SB_HORZ,&bar_pos,TRUE);
  ShowScrollBar(MainWnd,SB_HORZ,TRUE);
		  /* determine the part of screen in which to draw data, bounded by rect */
  GetClientRect(MainWnd,&rect);		/* vertical size has changed due to horizontal scroll bar */
  rect.left+=DISPLAY_COLS;
  fillrect=rect;
  brush=CreateSolidBrush(RGB(255,255,255));
  FillRect(hDC,&fillrect,brush);		/* clear right-side half of window */
  fillrect.top+=DISPLAY_ROWS;
  fillrect.left=0; fillrect.right=DISPLAY_COLS-1;
  FillRect(hDC,&fillrect,brush);		/* clear bottom-left quarter of window */
  DeleteObject(brush);
		  /* draw portion of data that is visible */
  for (j=0; j<7; j++)
	midline[j]=j*(rect.bottom/7)+(rect.bottom/7)/2;
		  /* draw gestures if loaded; doing this first so other stuff will overlay */
  if (TotalGTGestures > 0)
	{
	d_left=TimeIndex+0-DataDisplayWidth/2;								/* data index at left side of window */
	d_right=TimeIndex+DataDisplayWidth-1-DataDisplayWidth/2;			/* data index at right side of window */
	for (g=0; g<TotalGTGestures; g++)
	  {
	  if (GTGestureStart[g] > d_right  ||  GTGestureEnd[g] < d_left)
		continue;	/* no portion of this gesture is visible */
	  fillrect.top=midline[6]-18; fillrect.bottom=midline[6]-12;
	  if (GTGestureStart[g] < d_left)
		fillrect.left=rect.left;
	  else
		fillrect.left=rect.left+(GTGestureStart[g]-d_left);
	  if (GTGestureEnd[g] > d_right)
		fillrect.right=rect.right;
	  else
		fillrect.right=rect.left+(GTGestureEnd[g]-d_left);
	  brush=CreateSolidBrush(RGB(GestureColors[GTGestureType[g]][0],GestureColors[GTGestureType[g]][1],GestureColors[GTGestureType[g]][2]));
	  FillRect(hDC,&fillrect,brush);			/* draw rectangle for gesture */
	  fillrect.top=midline[6]-25; fillrect.bottom=midline[6]-5;  /* draw vertical ticks for boundary */
	  if (GTGestureStart[g] >= d_left)
		{
		fillrect.left=rect.left+(GTGestureStart[g]-d_left);
		fillrect.right=fillrect.left+1;
		FillRect(hDC,&fillrect,brush);
		}
	  if (GTGestureEnd[g] <= d_right)
		{
		fillrect.right=rect.left+(GTGestureEnd[g]-d_left);
		fillrect.left=fillrect.right-1;
		FillRect(hDC,&fillrect,brush);
		}
	  DeleteObject(brush);
	  }
	}
  if (TotalMDGestures > 0)
	{
	d_left=TimeIndex+0-DataDisplayWidth/2;								/* data index at left side of window */
	d_right=TimeIndex+DataDisplayWidth-1-DataDisplayWidth/2;			/* data index at right side of window */
	for (g=0; g<TotalMDGestures; g++)
	  {
	  if (MDGestureStart[g] > d_right  ||  MDGestureEnd[g] < d_left)
		continue;	/* no portion of this gesture is visible */
	  fillrect.top=midline[6]+5; fillrect.bottom=midline[6]+25;
	  if (MDGestureStart[g] < d_left)
		fillrect.left=rect.left;
	  else
		fillrect.left=rect.left+(MDGestureStart[g]-d_left);
	  if (MDGestureEnd[g] > d_right)
		fillrect.right=rect.right;
	  else
		fillrect.right=rect.left+(MDGestureEnd[g]-d_left);
	  brush=CreateSolidBrush(RGB(GestureColors[MDGestureType[g]][0],GestureColors[MDGestureType[g]][1],GestureColors[MDGestureType[g]][2]));
	  FillRect(hDC,&fillrect,brush);			/* draw rectangle for gesture */
	  DeleteObject(brush);
	  }
	}

  if (TotalPeaks > 0)
	{
	d_left=TimeIndex+0-DataDisplayWidth/2;								/* data index at left side of window */
	d_right=TimeIndex+DataDisplayWidth-1-DataDisplayWidth/2;			/* data index at right side of window */
	for (g=0; g<TotalPeaks; g++)
	  {
	  if (PeakLeft[g] > d_right  ||  PeakRight[g] < d_left)
		continue;	/* no portion of this peak is visible */
	  fillrect.top=midline[5]-18; fillrect.bottom=midline[5]-12;
	  if (PeakLeft[g] < d_left)
		fillrect.left=rect.left;
	  else
		fillrect.left=rect.left+(PeakLeft[g]-d_left);
	  if (PeakRight[g] > d_right)
		fillrect.right=rect.right;
	  else
		fillrect.right=rect.left+(PeakRight[g]-d_left);
	  brush=CreateSolidBrush(RGB(150,220,150+(PeakType[g]*100)));
	  FillRect(hDC,&fillrect,brush);			/* draw rectangle for gesture */
	  fillrect.top=midline[5]-25; fillrect.bottom=midline[5]-5;  /* draw vertical ticks for boundary */
	  if (PeakLeft[g] >= d_left)
		{
		fillrect.left=rect.left+(PeakLeft[g]-d_left);
		fillrect.right=fillrect.left+1;
		FillRect(hDC,&fillrect,brush);
		}
	  if (PeakRight[g] <= d_right)
		{
		fillrect.right=rect.left+(PeakRight[g]-d_left);
		fillrect.left=fillrect.right-1;
		FillRect(hDC,&fillrect,brush);
		}
	  DeleteObject(brush);
	  }
	}

  for (p=0; p<DataDisplayWidth; p++)
	{
	d=TimeIndex+p-DataDisplayWidth/2;			/* data index to draw */
	if (d < 0  ||  d >= TotalData)
	  continue;
	x=rect.left+p;								/* horizontal position to draw at */
	for (j=0; j<7; j++)
	  {
	  if (DisplayRollOnly == 1  &&  j != 5)
		continue;
	  if (DisplayAccs == 0  &&  j >= 0  &&  j <= 2)
		continue;
	  if (DisplayGyros == 0  &&  j >= 3  &&  j <= 5)
		continue;
	  if (DisplayScale == 0  &&  j == 6)
		continue;
	  y=midline[j];								/* vertical position to draw at (mid-y) */
	  linearray[0].x=linearray[1].x=(long)x;
	  if (j == 6)
		linearray[0].y=(long)(y-(int)((Data[j][d]-ScaleAverage)*DataStretch[j]));
	  else if (ViewSmoothed == 0)
		linearray[0].y=(long)(y-(int)(Data[j][d]*DataStretch[j]));		/* minus so - goes upwards, scaled by stretch (mag factor) */
	  else if (ViewSmoothed == 1)
		linearray[0].y=(long)(y-(int)(SmoothedData[j][d]*DataStretch[j]));
	  linearray[1].y=linearray[0].y+2;			/* 2-pixel wide "tick" */
	  //linearray[1].y=(long)(y-(int)(Data[j][d+1]*DataStretch[j]));			/* connected to next data */
	  if (linearray[0].y > rect.top  &&  linearray[0].y < rect.bottom  &&  linearray[1].y > rect.top  &&  linearray[1].y < rect.bottom)
		Polyline(hDC,linearray,2);
	  }
		/* display GT bite marker if there is one at this location */
	for (j=0; j<TotalGTBites; j++)
	  {
	  if (GTBiteIndex[j] == d)
		{
		brush=CreateSolidBrush(RGB(200,200,255));
		fillrect.left=linearray[0].x;
		fillrect.right=linearray[0].x+2;
		fillrect.top=0;
		fillrect.bottom=rect.bottom;
		if (DisplayGT)
		  FillRect(hDC,&fillrect,brush);	  /* draw bluish bar on center point */
		DeleteObject(brush);
		if (DisplayEvaluationLinks == 1  &&  GTMatched[j] != NOT_MATCHED)
		  {
		  brush=CreateSolidBrush(RGB(200,100,235));
		  d_left=TimeIndex+0-DataDisplayWidth/2;								/* data index at left side of window */
		  d_right=TimeIndex+DataDisplayWidth-1-DataDisplayWidth/2;			/* data index at right side of window */
		  if (GTMatched[j] < d_left)
			fillrect.left=rect.left;
		  else if (GTMatched[j] > d_right)
			fillrect.right=rect.right;
		  else
			fillrect.left=rect.left+(GTMatched[j]-d_left);
		  fillrect.right=linearray[0].x;
		  if (fillrect.left > fillrect.right)
			{
			temp_swap=fillrect.left;
			fillrect.left=fillrect.right;
			fillrect.right=temp_swap;
			}
		  if (fillrect.right-fillrect.left < 10)
			fillrect.right=fillrect.left+10;
		  fillrect.top=midline[5]-30;
		  fillrect.bottom=midline[5]-20;
		  FillRect(hDC,&fillrect,brush);	  /* draw horizontal link connecting GT-MD bites */
		  DeleteObject(brush);
		  }
		}
	  }
		/* display MD bite marker if there is one at this location */
	if (DisplayMDBites)
	  {
	  for (j=0; j<TotalMDBites; j++)
		{
		if (MDBiteIndex[j] == d)
		  {
		  brush=CreateSolidBrush(RGB(255,0,0));
		  fillrect.left=linearray[0].x-2;
		  fillrect.right=linearray[0].x+4;
		  fillrect.top=midline[5]-20;
		  fillrect.bottom=midline[5]+20;
		  FillRect(hDC,&fillrect,brush);	  /* draw red bar on center point */
		  DeleteObject(brush);
		  }
		}
	  }
		/* center point, print more info about it */
	if (p == DataDisplayWidth/2)
	  {
	  brush=CreateSolidBrush(RGB(0,255,0));
	  fillrect.left=linearray[0].x-1;
	  fillrect.right=linearray[0].x+1;
	  fillrect.top=0;
	  fillrect.bottom=rect.bottom;
	  FillRect(hDC,&fillrect,brush);	  /* draw green bar on center point */
	  DeleteObject(brush);
	  for (j=0; j<7; j++)				  /* print out the data numbers */
		{
		if (DisplayRollOnly == 1  &&  j != 5)
		  continue;
		if (DisplayAccs == 0  &&  j >= 0  &&  j <= 2)
		  continue;
		if (DisplayGyros == 0  &&  j >= 3  &&  j <= 5)
		  continue;
		if (DisplayScale == 0  &&  j == 6)
		  continue;
		if (j == 6  ||  ViewSmoothed == 0)
		  sprintf(text,"%.2lf  ",Data[j][d]);
		else if (ViewSmoothed == 1)
		  sprintf(text,"%.2lf  ",SmoothedData[j][d]);
		TextOut(hDC,fillrect.right+5,midline[j]+20,text,strlen(text));
		}
	  sprintf(textout,"Data %d of %d  time %02d:%02d     ",TimeIndex,TotalData,(TimeIndex/15)/60,(TimeIndex/15)%60);
	  TextOut(hDC,fillrect.right+5,rect.top+10,textout,strlen(textout));
		/* display GT bite info if there is one at this location */
	  for (j=0; j<TotalGTBites; j++)
		if (GTBiteIndex[j] == d)
		  {
		  TextOut(hDC,20,DISPLAY_ROWS+10,GTBiteHand[j],strlen(GTBiteHand[j]));
		  TextOut(hDC,120,DISPLAY_ROWS+10,GTBiteUtensil[j],strlen(GTBiteUtensil[j]));
		  TextOut(hDC,220,DISPLAY_ROWS+10,GTBiteContainer[j],strlen(GTBiteContainer[j]));
		  TextOut(hDC,20,DISPLAY_ROWS+30,GTBiteFood[j],strlen(GTBiteFood[j]));
		  }
		/* draw scale image for this time index */
	  if (scale_video != NULL)
		{
		for (j=0; j<SCALE_ROWS*SCALE_COLS; j++)
		  scale_image[j]=scale_video[(d*SCALE_ROWS*SCALE_COLS)+j];
		for (r=0; r<SCALE_ROWS; r++)
		  for (c=0; c<SCALE_COLS; c++)
			{
			brush=CreateSolidBrush(RGB(255,0,0));
			fillrect.left=50+c*SCALE_WINDOW;
			fillrect.right=fillrect.left+SCALE_WINDOW;
			fillrect.top=DISPLAY_ROWS+200+r*SCALE_WINDOW;
			fillrect.bottom=fillrect.top+SCALE_WINDOW;
			FillRect(hDC,&fillrect,brush);
			DeleteObject(brush);
			brush=CreateSolidBrush(RGB(scale_image[r*SCALE_COLS+c],scale_image[r*SCALE_COLS+c],scale_image[r*SCALE_COLS+c]));
			fillrect.left=50+c*SCALE_WINDOW+1;
			fillrect.right=fillrect.left+SCALE_WINDOW-2;
			fillrect.top=DISPLAY_ROWS+200+r*SCALE_WINDOW+1;
			fillrect.bottom=fillrect.top+SCALE_WINDOW-2;
			FillRect(hDC,&fillrect,brush);
			DeleteObject(brush);
			}
		}
	  }
	}

  if (FoodsLoaded)
	{
	sprintf(text,"kcals");
	TextOut(hDC,20,DISPLAY_ROWS+60,text,strlen(text));
	sprintf(text,"bites");
	TextOut(hDC,70,DISPLAY_ROWS+60,text,strlen(text));
	sprintf(text,"kpb");
	TextOut(hDC,120,DISPLAY_ROWS+60,text,strlen(text));
	sprintf(text,"food");
	TextOut(hDC,160,DISPLAY_ROWS+60,text,strlen(text));
	for (j=0; j<TotalFoodsInMeal; j++)
	  {
	  sprintf(text,"%d",FoodKcals[j]);
	  TextOut(hDC,20,DISPLAY_ROWS+80+j*20,text,strlen(text));
	  sprintf(text,"%d",FoodBites[j]);
	  TextOut(hDC,70,DISPLAY_ROWS+80+j*20,text,strlen(text));
	  sprintf(text,"%.1f",FoodKPB[j]);
	  TextOut(hDC,120,DISPLAY_ROWS+80+j*20,text,strlen(text));
	  sprintf(text,"%s",FoodsInMeal[j]);
	  TextOut(hDC,160,DISPLAY_ROWS+80+j*20,text,strlen(text));
	  }
	}

	  /* draw legend for gesture colors if there are any displayed */
  if (TotalGTGestures > 0  ||  TotalMDGestures > 0)
	{
	for (g=0; g<5; g++)
	  {
	  brush=CreateSolidBrush(RGB(GestureColors[g][0],GestureColors[g][1],GestureColors[g][2]));
	  fillrect.top=DISPLAY_ROWS+100+g*20;
	  fillrect.bottom=DISPLAY_ROWS+115+g*20;
	  fillrect.left=20; fillrect.right=35;
	  FillRect(hDC,&fillrect,brush);
	  DeleteObject(brush);
	  TextOut(hDC,40,fillrect.top,GestureNames[g],strlen(GestureNames[g]));
	  }
	}

		/* plot inter-bite intervals; if TimeIndex is on a bite then highlight and display its IBI */
  if (0) // TotalGTBites > 0)
	{
	for (j=1; j<TotalGTBites; j++)
	  {
	  if (GTBiteIndex[j] == TimeIndex)
		{
		brush=CreateSolidBrush(RGB(100,255,80));
		sprintf(text,"spb: %.1f",(float)(GTBiteIndex[j]-GTBiteIndex[j-1])/15.0);
		TextOut(hDC,25+TotalGTBites*5,DISPLAY_ROWS+230,text,strlen(text));
		}
	  else
		brush=CreateSolidBrush(RGB(200,200,255));
	  IBI=(GTBiteIndex[j]-GTBiteIndex[j-1])/15;
	  fillrect.left=20+j*5;
	  fillrect.right=fillrect.left+5;
	  fillrect.bottom=DISPLAY_ROWS+250;
	  fillrect.top=fillrect.bottom-IBI;
	  FillRect(hDC,&fillrect,brush);	  /* draw bluish bar with height denoting inter-bite interval (in seconds) */
	  DeleteObject(brush);
	  }
	IBI_average=IBI_stddev=0.0;
	for (j=1; j<TotalGTBites; j++)
	  IBI_average+=(double)(GTBiteIndex[j]-GTBiteIndex[j-1])/15.0;
	IBI_average/=(double)(TotalGTBites-1);
	for (j=1; j<TotalGTBites; j++)
	  IBI_stddev+=SQR((double)(GTBiteIndex[j]-GTBiteIndex[j-1])/15.0-IBI_average);
	IBI_stddev=sqrt(IBI_stddev/(double)(TotalGTBites-2));
	sprintf(text,"spb avg (stddev): %.1lf (%.1lf)",IBI_average,IBI_stddev);
	TextOut(hDC,20,DISPLAY_ROWS+270,text,strlen(text));
	}

		/* plot bites/sec and cycles/sec */
  if (0  &&  TotalGTBites > 0   &&  TotalMDBites > 0)
	{
	for (i=0; i<TotalData; i+=(15*10))	/* measured once per ten seconds */
	  {
	  BitesPerMin[i/(15*10)]=CyclesPerMin[i/(15*10)]=0;
	  for (j=0; j<TotalGTBites; j++)
		{
		if (GTBiteIndex[j] >= i-(15*60)  &&  GTBiteIndex[j] < i)
		  BitesPerMin[i/(15*10)]++;
		}
	  for (j=0; j<TotalMDBites; j++)
		{
		if (MDBiteIndex[j] >= i-(15*60)  &&  MDBiteIndex[j] < i)
		  CyclesPerMin[i/(15*10)]++;
		}
	  }

	for (i=0; i<TotalData/(15*10); i++)
	  {
	  brush=CreateSolidBrush(RGB(200,200,255));
	  fillrect.left=20+i*5;
	  fillrect.right=fillrect.left+5;
	  fillrect.bottom=DISPLAY_ROWS+250;
	  fillrect.top=fillrect.bottom-(CyclesPerMin[i]*10);	  /* draw bluish bar with height denoting cycles per min */
	  FillRect(hDC,&fillrect,brush);
	  DeleteObject(brush);
	  brush=CreateSolidBrush(RGB(100,255,80));
	  fillrect.left=20+i*5;
	  fillrect.right=fillrect.left+5;
	  fillrect.bottom=DISPLAY_ROWS+350;
	  fillrect.top=fillrect.bottom-(BitesPerMin[i]*10);	  /* draw greenish bar with height denoting bites per min */
//	  fillrect.top=fillrect.bottom-(int)(((double)CyclesPerMin[i]/(double)BitesPerMin[i])*20.0);	  /* draw greenish bar with height denoting CPM/BPM ratio */
	  FillRect(hDC,&fillrect,brush);
	  DeleteObject(brush);
	  }
	BPM_average=BPM_stddev=CPM_average=CPM_stddev=covar=0.0;
	for (i=0; i<TotalData/(15*10); i++)
	  {
	  BPM_average+=(double)(BitesPerMin[i]);
	  CPM_average+=(double)(CyclesPerMin[i]);
	  }
	BPM_average/=(double)(TotalData/(15*10));
	CPM_average/=(double)(TotalData/(15*10));
		/* calculate CPM/CPM(avg) (looking to see if it has a more stable line fit) */
	for (i=0; i<TotalData/(15*10); i++)
	  CyclesPerMinRatio[i]=((double)CyclesPerMin[i]/CPM_average);
		/* calculate stddevs and covar from which r and line params can be obtained */
	for (i=0; i<TotalData/(15*10); i++)
	  {
	  BPM_stddev+=(double)(SQR(BitesPerMin[i]-BPM_average));
	  CPM_stddev+=(double)(SQR(CyclesPerMin[i]-CPM_average));
//	  CPM_stddev+=(double)(SQR(CyclesPerMinRatio[i]-1.0));	  /* avg is always 1.0 */
	  covar+=(double)((CyclesPerMin[i]-CPM_average)*(BitesPerMin[i]-BPM_average));
//	  covar+=(double)((CyclesPerMinRatio[i]-1.0)*(BitesPerMin[i]-BPM_average));
	  }
	sprintf(text,"r: %.2lf",covar/(sqrt(BPM_stddev)*sqrt(CPM_stddev)));
	TextOut(hDC,20,DISPLAY_ROWS+400,text,strlen(text));
	sprintf(text,"BPM=%.2lf + %.2lf CPM",BPM_average-(covar/CPM_stddev)*CPM_average,covar/CPM_stddev);
//	sprintf(text,"BPM=%.2lf + %.2lf CPM",BPM_average-(covar/CPM_stddev)*1.0,covar/CPM_stddev);
	TextOut(hDC,200,DISPLAY_ROWS+400,text,strlen(text));
	sprintf(text,"BPM(avg)=%.1lf  CPM(avg)=%.1lf",BPM_average,CPM_average);
	TextOut(hDC,200,DISPLAY_ROWS+420,text,strlen(text));
	}

  ReleaseDC(MainWnd,hDC);
  }

if (VideoLoaded  &&  disp_image != NULL)
  {
  ReadVideoFrame(TimeIndex*1000/15+VideoSyncOffset,disp_image);	/* *1000/15 converts 15Hz data to milliseconds */

  BeginPaint(MainWnd,&Painter);
  hDC=GetDC(MainWnd);
  bm_info_header.biSize=sizeof(BITMAPINFOHEADER); 
  bm_info_header.biWidth=DISPLAY_COLS;
  bm_info_header.biHeight=-DISPLAY_ROWS; 
  bm_info_header.biPlanes=1;
  bm_info_header.biBitCount=24; 
  bm_info_header.biCompression=BI_RGB; 
  bm_info_header.biSizeImage=0; 
  bm_info_header.biXPelsPerMeter=0; 
  bm_info_header.biYPelsPerMeter=0;
  bm_info_header.biClrUsed=0; 
  bm_info_header.biClrImportant=0;
  // bm_info.bmiColors=NULL;
  bm_info.bmiHeader=bm_info_header;
  SetDIBitsToDevice(hDC,0,0,DISPLAY_COLS,DISPLAY_ROWS,0,0,
				0, /* first scan line */
				DISPLAY_ROWS, /* number of scan lines */
				disp_image,&bm_info,DIB_RGB_COLORS);
  ReleaseDC(MainWnd,hDC);
  EndPaint(MainWnd,&Painter);
  }
}



		/* dialog box for obtaining bite details */

#define TOTAL_HANDS	3
#define TOTAL_UTENSILS 7
#define TOTAL_CONTAINERS 8
#define TOTAL_FOODS 12

LRESULT CALLBACK RecordBiteInfo(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)

{
int		  i;
char	  *hand[TOTAL_HANDS] = {"left", "right", "both"};
char	  *utensil[TOTAL_UTENSILS] = {"hand", "fork", "spoon", "knife", "straw", "chopsticks","other"};
char	  *container[TOTAL_CONTAINERS] = {"plate", "bowl", "table", "container", "glass", "mug", "bottle", "other"};
static char	  food[TOTAL_FOODS][80];
int		  EditIndex;	/* determines if this is new or existing bite */

switch(uMsg)
  {
  case WM_INITDIALOG:
		/* build foods list */
	for (i=0; i<TOTAL_FOODS; i++)
	  {
	  if (i < TotalFoodsInMeal)
		strcpy(food[i],FoodsInMeal[i]);
	  else
		strcpy(food[i],"unknown");
	  SetDlgItemText(hDlg,IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS+TOTAL_CONTAINERS+i,food[i]);
	  }
		/* if editing bite, change current pattern variables to existing bite details, unlesss food = unknown */
	for (EditIndex=0; EditIndex<TotalGTBites; EditIndex++)
	  if (GTBiteIndex[EditIndex] == TimeIndex)
		break;
	if (EditIndex < TotalGTBites  &&  !(strcmp(GTBiteFood[EditIndex],"unknown") == 0))
	  {
	  for (i=0; i<TOTAL_HANDS; i++)
		if (strcmp(hand[i],GTBiteHand[EditIndex]) == 0)
		  break;
	  if (i < TOTAL_HANDS)
		CurrentHand=i;
	  for (i=0; i<TOTAL_UTENSILS; i++)
		if (strcmp(utensil[i],GTBiteUtensil[EditIndex]) == 0)
		  break;
	  if (i < TOTAL_UTENSILS)
		CurrentUtensil=i;
	  for (i=0; i<TOTAL_CONTAINERS; i++)
		if (strcmp(container[i],GTBiteContainer[EditIndex]) == 0)
		  break;
	  if (i < TOTAL_CONTAINERS)
		CurrentContainer=i;
	  for (i=0; i<TOTAL_FOODS; i++)
		if (strcmp(food[i],GTBiteFood[EditIndex]) == 0)
		  break;
	  if (i < TOTAL_FOODS)
		CurrentFood=i;
	  }
		/* initialize radio buttons for current pattern variables */
	CheckRadioButton(hDlg,IDC_RADIO1,IDC_RADIO1+TOTAL_HANDS-1,IDC_RADIO1+CurrentHand);
	CheckRadioButton(hDlg,IDC_RADIO1+TOTAL_HANDS,
					  IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS-1,
					  IDC_RADIO1+TOTAL_HANDS+CurrentUtensil);
	CheckRadioButton(hDlg,IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS,
					  IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS+TOTAL_CONTAINERS-1,
					  IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS+CurrentContainer);
	CheckRadioButton(hDlg,IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS+TOTAL_CONTAINERS,
					  IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS+TOTAL_CONTAINERS+TOTAL_FOODS-1,
					  IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS+TOTAL_CONTAINERS+CurrentFood);
	break;
  case WM_COMMAND:
	if (LOWORD(wParam) >= IDC_RADIO1  &&
		LOWORD(wParam) < IDC_RADIO1+TOTAL_HANDS)
	  {
	  CurrentHand=LOWORD(wParam)-IDC_RADIO1;
	  CheckRadioButton(hDlg,IDC_RADIO1,IDC_RADIO1+TOTAL_HANDS-1,IDC_RADIO1+CurrentHand);
	  }
	else if (LOWORD(wParam) >= IDC_RADIO1+TOTAL_HANDS  &&
		LOWORD(wParam) < IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS)
	  {
	  CurrentUtensil=LOWORD(wParam)-IDC_RADIO1-TOTAL_HANDS;
	  CheckRadioButton(hDlg,IDC_RADIO1+TOTAL_HANDS,
					  IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS-1,
					  IDC_RADIO1+TOTAL_HANDS+CurrentUtensil);
	  }
	else if (LOWORD(wParam) >= IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS  &&
		LOWORD(wParam) < IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS+TOTAL_CONTAINERS)
	  {
	  CurrentContainer=LOWORD(wParam)-IDC_RADIO1-TOTAL_HANDS-TOTAL_UTENSILS;
	  CheckRadioButton(hDlg,IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS,
					  IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS+TOTAL_CONTAINERS-1,
					  IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS+CurrentContainer);
	  }
	else if (LOWORD(wParam) >= IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS+TOTAL_CONTAINERS  &&
		LOWORD(wParam) < IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS+TOTAL_CONTAINERS+TOTAL_FOODS)
	  {
	  CurrentFood=LOWORD(wParam)-IDC_RADIO1-TOTAL_HANDS-TOTAL_UTENSILS-TOTAL_CONTAINERS;
	  CheckRadioButton(hDlg,IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS+TOTAL_CONTAINERS,
					  IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS+TOTAL_CONTAINERS+TOTAL_FOODS-1,
					  IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS+TOTAL_CONTAINERS+CurrentFood);
	  }
	else switch(LOWORD(wParam))
	  {
	  case IDCANCEL:
		EndDialog(hDlg,IDOK);
		break;
	  case IDOK:
		for (EditIndex=0; EditIndex<TotalGTBites; EditIndex++)
		  if (TimeIndex == GTBiteIndex[EditIndex])
			break;
		GTBiteIndex[EditIndex]=TimeIndex;
		for (i=0; i<TOTAL_HANDS; i++)
		  if (IsDlgButtonChecked(hDlg,IDC_RADIO1+i) == BST_CHECKED)
			strcpy(GTBiteHand[EditIndex],hand[i]);
		for (i=0; i<TOTAL_UTENSILS; i++)
		  if (IsDlgButtonChecked(hDlg,IDC_RADIO1+TOTAL_HANDS+i) == BST_CHECKED)
			strcpy(GTBiteUtensil[EditIndex],utensil[i]);
		for (i=0; i<TOTAL_CONTAINERS; i++)
		  if (IsDlgButtonChecked(hDlg,IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS+i) == BST_CHECKED)
			strcpy(GTBiteContainer[EditIndex],container[i]);
		for (i=0; i<TOTAL_FOODS; i++)
		  if (IsDlgButtonChecked(hDlg,IDC_RADIO1+TOTAL_HANDS+TOTAL_UTENSILS+TOTAL_CONTAINERS+i) == BST_CHECKED)
			strcpy(GTBiteFood[EditIndex],food[i]);
		if (EditIndex == TotalGTBites)	/* is a new bite */
		  TotalGTBites++;
				/* auto-save all bites to protect work */
		SaveGT("gt_temp.txt");
		EndDialog(hDlg,IDOK);
		break;
		}
	  break;
	default:
	  return(FALSE);
  }
return(TRUE);
}



LRESULT CALLBACK ChangeFFSpeed(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)

{
char	  text[320];

switch(uMsg)
  {
  case WM_INITDIALOG:
	sprintf(text,"%d",FFspeed);
	SetDlgItemText(hDlg,IDC_EDIT1,text);
	break;
  case WM_COMMAND:
	switch(LOWORD(wParam))
	  {
	  case IDOK:
		GetDlgItemText(hDlg,IDC_EDIT1,text,320);
		FFspeed=atoi(text);
		if (FFspeed < 2)
		  FFspeed=2;
		if (FFspeed > 150)
		  FFspeed=150;
		EndDialog(hDlg,IDOK);
		break;
		}
	  break;
	default:
	  return(FALSE);
  }
return(TRUE);
}




LRESULT CALLBACK ChangeAnalysisParams(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)

{
char	  text[320];

switch(uMsg)
  {
  case WM_INITDIALOG:
	sprintf(text,"%.1lf",RollThresh);
	SetDlgItemText(hDlg,IDC_EDIT1,text);
	sprintf(text,"%d",Time1Thresh);
	SetDlgItemText(hDlg,IDC_EDIT2,text);
	sprintf(text,"%d",Time2Thresh);
	SetDlgItemText(hDlg,IDC_EDIT3,text);
	break;
  case WM_COMMAND:
	switch(LOWORD(wParam))
	  {
	  case IDOK:
		GetDlgItemText(hDlg,IDC_EDIT1,text,320);
		RollThresh=atof(text);
		GetDlgItemText(hDlg,IDC_EDIT2,text,320);
		Time1Thresh=atoi(text);
		GetDlgItemText(hDlg,IDC_EDIT3,text,320);
		Time2Thresh=atoi(text);
		EndDialog(hDlg,IDOK);
		break;
		}
	  break;
	default:
	  return(FALSE);
  }
return(TRUE);
}
