
#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 "globals.h"
#include "resource.h"

int APIENTRY WinMain(HINSTANCE hInstance,
					 HINSTANCE hPrevInstance,
					 LPSTR lpCmdLine,
					 int nCmdShow)

{
MSG			msg;
WNDCLASS	wc;
LRESULT		CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
FILE		*fpt;
int			i;

wc.style=CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc=(WNDPROC)WndProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInstance;
hInst=hInstance;
wc.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(ID_ICON));
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName=MAKEINTRESOURCE(ID_MAIN_MENU);
wc.lpszClassName="GRIDVIEW";

if (!RegisterClass(&wc))
  return(FALSE);

MainWnd=CreateWindow("GRIDVIEW","Grid Scale Data Review",
			WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL | WS_MAXIMIZE,
			0,0,600+650,800,NULL,NULL,hInstance,NULL);
if (!MainWnd)
  return(FALSE);

ShowScrollBar(MainWnd,SB_BOTH,FALSE);
ShowWindow(MainWnd,SW_MAXIMIZE);
InvalidateRect(MainWnd,NULL,TRUE);
UpdateWindow(MainWnd);

		/* check for master list; allows scrolling through multiple files using keystrokes */
TotalFilenames=0;
fpt=fopen("WINDOWS_FILENAMES.txt","r");
if (fpt == NULL)
  fpt=fopen("..\\WINDOWS_FILENAMES.txt","r");
if (fpt != NULL)
  {
  while (1)
	{
	i=fscanf(fpt,"%s",NameList[TotalFilenames]);
	if (i != 1)
	  break;
	TotalFilenames++;
	}
  fclose(fpt);
  }

Data=SmoothedData=NULL;	/* space allocated in InitializeDataVariables() */

InitializeDataVariables();

while (GetMessage(&msg,NULL,0,0))
  {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
  }
return(msg.wParam);
}



LRESULT CALLBACK WndProc (HWND hWnd,
						  UINT uMsg,
						  WPARAM wParam,
						  LPARAM lParam)

{
int				i;
OPENFILENAME	ofn;
HMENU			hAppMenu;
char			text[320];

switch (uMsg)
  {
  case WM_COMMAND:
	switch (LOWORD(wParam))
	  {
	  case ID_FILE_LOAD:
		memset(&(ofn),0,sizeof(ofn));
		ofn.lStructSize=sizeof(ofn);
		ofn.lpstrFile=MasterFilename;
		MasterFilename[0]=0;
		ofn.nMaxFile=320;
		ofn.Flags=OFN_EXPLORER | OFN_HIDEREADONLY;
		ofn.lpstrFilter="Grid master files\0grid_files.txt\0All files\0*.*\0\0";
//		ofn.lpstrFilter="All files\0*.*\0\0";
		if (!( GetOpenFileName(&ofn))  ||  MasterFilename[0] == '\0')
		  break;
						/* set currentpath to where file loaded from */
		strcpy(CurrentPath,MasterFilename);
		i=strlen(CurrentPath)-1;
		while (i > 0  &&  CurrentPath[i] != '\\')
		  i--;
		CurrentPath[i]='\0';
		SetCurrentDirectory((LPCTSTR)CurrentPath);
		if (VideoLoaded)
		  {
		  if (disp_image != NULL)
			{
			free(disp_image);
			disp_image=NULL;
			}
		  CloseVideoFile();
		  }
		InitializeDataVariables();
		ReadFiles();
		sprintf(text,"Grid Scale Data Review   %s",DataFilename);
		SetWindowText(hWnd,text);
		PaintImage();
		break;

	  case ID_DATA_SMOOTH:
		ViewSmoothed=(ViewSmoothed+1)%2;
		hAppMenu=GetMenu(hWnd);
		if (ViewSmoothed == 1)
		  CheckMenuItem(hAppMenu,ID_DATA_SMOOTH,MF_CHECKED);
		else
		  CheckMenuItem(hAppMenu,ID_DATA_SMOOTH,MF_UNCHECKED);
		PaintImage();
		break;
	  case ID_DISPLAY_WEIGHTS:
		DisplayWeights=(DisplayWeights+1)%2;
		hAppMenu=GetMenu(hWnd);
		if (DisplayWeights == 1)
		  CheckMenuItem(hAppMenu,ID_DISPLAY_WEIGHTS,MF_CHECKED);
		else
		  CheckMenuItem(hAppMenu,ID_DISPLAY_WEIGHTS,MF_UNCHECKED);
		PaintImage();
		break;
	  case ID_DISPLAY_PLOTS:
		DisplayPlots=(DisplayPlots+1)%2;
		hAppMenu=GetMenu(hWnd);
		if (DisplayPlots == 1)
		  CheckMenuItem(hAppMenu,ID_DISPLAY_PLOTS,MF_CHECKED);
		else
		  CheckMenuItem(hAppMenu,ID_DISPLAY_PLOTS,MF_UNCHECKED);
		PaintImage();
		break;
	  case ID_DISPLAY_REGIONS:
		DisplayRegions=(DisplayRegions+1)%2;
		hAppMenu=GetMenu(hWnd);
		if (DisplayRegions == 1)
		  CheckMenuItem(hAppMenu,ID_DISPLAY_REGIONS,MF_CHECKED);
		else
		  CheckMenuItem(hAppMenu,ID_DISPLAY_REGIONS,MF_UNCHECKED);
		PaintImage();
		break;

	  case ID_EDIT_FF_SPEED:
		DialogBox(hInst,MAKEINTRESOURCE(IDD_FF_DIALOG),hWnd,(DLGPROC)ChangeFFSpeed);
		PaintImage();
		break;

	  case ID_HELP_KEYS:
		sprintf(text,"Key(s)\tAction(s)\n-------------------------------------------------\n");
		strcat(text,"asdfg\tplayback controls   << < [] > >>\n");
		strcat(text,"-+\tload prev/next file\n");
		strcat(text,"v\tcalculate video sync offset\n");
		MessageBox(hWnd,text,"Keyboard controls",MB_OK | MB_APPLMODAL);
		break;

	  case ID_QUIT:
		if (VideoLoaded)
		  {
		  if (disp_image != NULL)
			{
			free(disp_image);
			disp_image=NULL;
			}
		  CloseVideoFile();
		  VideoLoaded=0;
		  }
		Sleep(100);
		DestroyWindow(hWnd);
		break;
		
	  }
	break;

  case WM_HSCROLL:
	if (Playing == 1)
	  break;
	if (LOWORD(wParam) == SB_LINELEFT)  
	  {
	  if (TimeIndex-1 < 0)
		TimeIndex=0; 
	  else
		TimeIndex--;
	  }
	if (LOWORD(wParam) == SB_LINERIGHT) 
	  {
	  if (TimeIndex+1 > TotalData-1)
		TimeIndex=TotalData-1;
	  else
		TimeIndex++;
	  }
	if (LOWORD(wParam) == SB_PAGELEFT) 
	  {
	  if (TimeIndex-DataDisplayWidth < 0)
		TimeIndex=0; 
	  else
		TimeIndex-=DataDisplayWidth;		
	  }
	if (LOWORD(wParam) == SB_PAGERIGHT)
	  {	
	  if (TimeIndex+DataDisplayWidth > TotalData-1)
		TimeIndex=TotalData-1; 
	  else
		TimeIndex+=DataDisplayWidth;
	  }
	if (LOWORD(wParam) == SB_THUMBPOSITION)
	  {
	  TimeIndex=HIWORD(wParam);
	  }
	PaintImage();
	break;

  case WM_CHAR:
									/* all these controls set the current PlayJump */
	if (((TCHAR)wParam == 'a') || ((TCHAR)wParam == 'A'))
 	  {
	  PlayJump=((TCHAR)wParam == 'a' ? -FFspeed : -FFspeed*5);
	  UpdateDisplay();
	  }
	if (((TCHAR)wParam == 's') || ((TCHAR)wParam == 'S'))
 	  {
	  PlayJump=-1;
	  UpdateDisplay();
	  }
	if (((TCHAR)wParam == 'f') || ((TCHAR)wParam == 'F'))
 	  {
	  PlayJump=+1;
	  UpdateDisplay();
	  }
	if (((TCHAR)wParam == 'g') || ((TCHAR)wParam == 'G'))
 	  {
	  PlayJump=((TCHAR)wParam == 'g' ? FFspeed : FFspeed*5);
	  UpdateDisplay();
	  }
	if (((TCHAR)wParam == 'd') || ((TCHAR)wParam == 'D'))
	  {	
	  Playing=(Playing+1)%2;
	  if (Playing == 1)
		SetTimer(hWnd,TIMER_SECOND,PlayDelay,NULL);
	  else
		KillTimer(hWnd,TIMER_SECOND);
	  UpdateDisplay();
	  }
	if (((TCHAR)wParam == 'v') || ((TCHAR)wParam == 'V'))
	  {
	  for (i=0; i<TotalData; i++)
		if (Data[(i*GRID_ROWS*GRID_COLS)+0] > 10.0)
		  break;
	  sprintf(text,"Offset between current index and marker:  %d",(TimeIndex-i)*100+VideoSyncOffset);
	  MessageBox(hWnd,text,"Calculating video sync",MB_OK | MB_APPLMODAL);
	  PaintImage();
	  }
	if ((TCHAR)wParam == '-'  ||  (TCHAR)wParam == '+')
	  {
	  for (i=0; i<TotalFilenames; i++)
		if (strcmp(NameList[i],MasterFilename) == 0)
		  break;
	  if ((TCHAR)wParam == '-'  &&  i > 0)
		strcpy(MasterFilename,NameList[i-1]);
	  else if ((TCHAR)wParam == '+'  &&  i < TotalFilenames-1)
		strcpy(MasterFilename,NameList[i+1]);
	  else if (DataLoaded == 0  &&  TotalFilenames > 0)
		strcpy(MasterFilename,NameList[0]);
	  else
		break;	  /* no change; do not reload */
	  strcpy(CurrentPath,MasterFilename);
	  i=strlen(CurrentPath)-1;
	  while (i > 0  &&  CurrentPath[i] != '\\')
		i--;
	  CurrentPath[i]='\0';
	  SetCurrentDirectory((LPCTSTR)CurrentPath);
	  if (VideoLoaded)
		{
		if (disp_image != NULL)
		  {
		  free(disp_image);
		  disp_image=NULL;
		  }
		CloseVideoFile();
		}
	  InitializeDataVariables();
	  ReadFiles();
	  sprintf(text,"Cafeteria Data Review   %s",DataFilename);
	  SetWindowText(hWnd,text);
	  PaintImage();
	  }
	break;


  case WM_SIZE:
	if (hWnd != hWnd  ||  GetUpdateRect(hWnd,NULL,FALSE) == 0)
	  return(DefWindowProc(hWnd,uMsg,wParam,lParam));
	break;

  case WM_PAINT:
	PaintImage();
	return(DefWindowProc(hWnd,uMsg,wParam,lParam));
	break;

  case WM_TIMER:
	if (wParam == TIMER_SECOND)
	  {
	  UpdateDisplay();
	  }
	break;

  case WM_DESTROY:
	Sleep(100);
	DestroyWindow(hWnd);
	PostQuitMessage(0);
	break;
	
  default:
	return(DefWindowProc(hWnd,uMsg,wParam,lParam));
	break;
  }

return(0L);
}




		/* moves the TimeIndex according to PlayJump, then calls PaintImage() */

void UpdateDisplay()

{
if (TimeIndex+PlayJump < 0  ||  TimeIndex+PlayJump >= TotalData)
  {
  if (TimeIndex+PlayJump < 0)
	TimeIndex=0;
  else
	TimeIndex=TotalData-1;
  if (Playing == 1)		  /* halt play if reached either start or end */
	{
	KillTimer(MainWnd,TIMER_SECOND);
	Playing=0;
	}
  }
else
  {
  TimeIndex+=PlayJump;
  }
PaintImage();
}



void InitializeDataVariables()

{
if (Data != NULL)
  free(Data);
Data=(double *)calloc(MAX_DATA*GRID_COLS*GRID_ROWS,sizeof(double));
if (SmoothedData != NULL)
  free(SmoothedData);
SmoothedData=(double *)calloc(MAX_DATA*GRID_COLS*GRID_ROWS,sizeof(double));
TimeIndex=0;
VideoLoaded=0;
DataLoaded=0;
Playing=0;
PlayJump=1;
FFspeed=10;
PlayDelay=100;
TotalData=0;
disp_image=NULL;
ViewSmoothed=1;
DisplayWeights=1;
DisplayPlots=0;
DisplayRegions=0;
}