// McStar.cpp : Defines the entry point for the application.

#include "stdafx.h"
#include "MapIO.hpp"
#include "gpio.h"
#include "ssp.h"
#include "clk.h"
#include "resource.h"
#include "McStar.h"
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "ADSmartIO_load.h"
#include <commctrl.h>
#include <storemgr.h>

volatile GPIO_REGS		*GpioRegPtr = NULL;
volatile SSP_REGS		*SspRegPtr  = NULL;
volatile CLKMAN_REGS	*v_pClkRegs	= NULL;

int		fileListNum;
bool	powerDownUSB;
HANDLE	g_hCopyFileThread = 0;   
CFGDATA	configData;
TCHAR	fileList[2][1000][100];


void CreateFilename(TCHAR fileName[80], int fileType)
{
	TCHAR	cTemp[10];

	__time64_t t64Time;
    
	struct tm timeNow;
    
	_time64( &t64Time );
	if( (_localtime64_s(&timeNow, &t64Time)) !=0)
	{
		// process error
	}

	switch( fileType)
	{
/*		case 0:	//USB file
			wcscpy(fileName, (TEXT("\\Hard Disk\\McSTAR\\Data\\")));
			break;  */
		case 1:	//Flash File
			wcscpy(fileName, (TEXT("\\Storage Card\\McSTAR\\Data\\")));
			break;  
		case 2:	//Log File
			wcscpy(fileName, (TEXT("\\Storage Card\\McSTAR\\LogFiles\\log")));
			break;
	}

	wsprintf(cTemp,L"%03d-",timeNow.tm_year);
	wcscat(fileName, cTemp);
	wsprintf(cTemp,L"%03d-",timeNow.tm_yday);
	wcscat(fileName, cTemp);
	wsprintf(cTemp,L"%02d-",timeNow.tm_hour);
	wcscat(fileName, cTemp);
	wsprintf(cTemp,L"%02d-",timeNow.tm_min);
	wcscat(fileName, cTemp);
	wsprintf(cTemp,L"%02d",timeNow.tm_sec);
	wcscat(fileName, cTemp);

/*
	_itow(timeNow.tm_year, cTemp, 10);
	wcscat(cTemp, (TEXT("-")));
	wcscat(fileName, cTemp);
	_itow(timeNow.tm_yday, cTemp, 10);
	wcscat(cTemp, (TEXT("-")));
	wcscat(fileName, cTemp);
	_itow(timeNow.tm_hour, cTemp, 10);
	wcscat(cTemp, (TEXT("-")));
	wcscat(fileName, cTemp);
	_itow(timeNow.tm_min, cTemp, 10);
	wcscat(cTemp, (TEXT("-")));
	wcscat(fileName, cTemp);
	_itow(timeNow.tm_sec, cTemp, 10);
	wcscat(fileName, cTemp);
*/

	if( fileType == 2 )
		wcscat(fileName, L".txt");

	return;
}


int ReadSSPWriteCF( unsigned int* ptr, int numSamples, TCHAR fileName[80] )
{	int				i,
					count,
					numWritten;
	unsigned int	ADCValue;
	char			cTemp[200], cTemp2[200];
	DWORD			time1, time2, dwTemp;
	FILE			*outFile;

	CreateFilename( fileName, FLASHFILE );

	outFile = _wfopen( fileName, (TEXT("ab")));

//	numWritten = fwrite(data, sizeof(int), numValues, outFile);
//	DEBUGMSG(1, (_T("Wrote %d samples to Flash Disk \n"), numWritten));
	
	time1 = GetTickCount();
	for(i=0; i<numSamples; i++)
	{
		count=0x3ffff;
		while((READ_REGISTER_ULONG(&SspRegPtr->SSSR) & SSSR_RNE) == 0)
		{
			if(count-- == 0)
				break;
		}

		if( count <= 0)
		{
			WriteLog(1,1,1, "Read SSP timed out with RNE = 0");
			return 0xFFFFFFFF;
		}
		else
		{	
			ADCValue = READ_REGISTER_ULONG(&SspRegPtr->SSDR);
			fwrite(&ADCValue, sizeof(int), 1, outFile);
//			DEBUGMSG(1,(TEXT("Count = %08x SSDR Register = %08x \n"), count, value));
		}
	}
	time2 = GetTickCount();
	dwTemp = time2 - time1;
	sprintf(cTemp, "Acq Done   Acquire Time = %d mSec", dwTemp);	
	WriteLog(1,1,1, cTemp);

	fclose(outFile);

	wcstombs(cTemp2, fileName, 80);
	sprintf(cTemp, "Wrote %d samples to %s", numSamples, cTemp2);
	WriteLog(1,1,1, cTemp);

	return i;
}

DWORD WINAPI copyFileThread (PVOID pArg) 
{
	int		i, j,
			offset,
			fileListNum;
	char	cTemp[200], cTemp2[200], cTemp3[200];
	DWORD	time1, time2, dwTemp;
	TCHAR	destFile[100],
			wcTemp[100],
			dirName[100];
	static int	dirCount = 0,
				filesInDir = 0;

//	CopyFileEx((_T("\\Storage Card\\McSTAR\\Data\\108-245-18-28-9.8")), (_T("\\Hard Disk\\McSTAR\\Data\\108-245-17-36-3.1")), (LPPROGRESS_ROUTINE)CopyProgressRoutine, NULL, NULL, NULL);	

	fileListNum = (int)pArg;
	WriteLog(1,1,1, "Thread Starting File Moves from CF to USB");
	if(filesInDir >=10)
	{
		dirCount = dirCount + 1;
		filesInDir = 0;
	}

	wcscpy(destFile, (TEXT("\\Hard Disk\\McSTAR\\Data")));
	wcscat(destFile, _itow(dirCount, wcTemp, 10)); 
	wcscat(destFile, (TEXT("\\")));
	CreateDirectory(destFile, NULL);

	offset = wcslen(destFile);

	time1 = GetTickCount();
	for(i=0; i<configData.numFlashFiles; i++)
	{
		j = 0;
		while(fileList[fileListNum][i][j] != 0)
		{
			destFile[j+offset] = fileList[fileListNum][i][j+offset+2];
			j = j + 1;
		}
		destFile[j] = 0;
		CopyFile(fileList[fileListNum][i], destFile, FALSE);
		filesInDir = filesInDir + 1;
		DeleteFile(fileList[fileListNum][i]);
		wcstombs(cTemp2, fileList[fileListNum][i], 80);
		wcstombs(cTemp3, destFile, 80);
		sprintf(cTemp, "Copy File Thread moved file %s to %s; fileListnum = %d", cTemp2, cTemp3, fileListNum);
		WriteLog(1,1,1, cTemp); 
	}
	time2 = GetTickCount();
	dwTemp = time2 - time1;
	sprintf(cTemp, "File Moves Done   Move Time = %d mSec", dwTemp);
	WriteLog(1,1,1, cTemp);
	sprintf(cTemp, "Battery Voltage = %8.2f counts\n", GetBatVoltage( 10 ));
	WriteLog(1,1,1, cTemp);
	if(powerDownUSB)
		SR_GPIOBit(107, 0);

	return 0;
}
int MoveFileCF2USB (PVOID pArg) 
{
	int		i, j,
			offset,
			fileListNum;
	char	cTemp[200], cTemp2[200], cTemp3[200];
	DWORD	time1, time2, dwTemp;
	TCHAR	destFile[100],
			wcTemp[100],
			dirName[100];
	static int	dirCount = 0,
				filesInDir = 0;

	fileListNum = (int)pArg;
	WriteLog(1,1,1, "Starting File Moves from CF to USB");
	if(filesInDir >=10)
	{
		dirCount = dirCount + 1;
		filesInDir = 0;
	}

	wcscpy(destFile, (TEXT("\\Hard Disk\\McSTAR\\Data")));
	wcscat(destFile, _itow(dirCount, wcTemp, 10)); 
	wcscat(destFile, (TEXT("\\")));
	CreateDirectory(destFile, NULL);

	offset = wcslen(destFile);

	time1 = GetTickCount();
	for(i=0; i<configData.numFlashFiles; i++)
	{
		j = 0;
		while(fileList[fileListNum][i][j] != 0)
		{
			destFile[j+offset] = fileList[fileListNum][i][j+offset+2];
			j = j + 1;
		}
		destFile[j] = 0;
		CopyFile(fileList[fileListNum][i], destFile, FALSE);
		filesInDir = filesInDir + 1;
		DeleteFile(fileList[fileListNum][i]);
		wcstombs(cTemp2, fileList[fileListNum][i], 80);
		wcstombs(cTemp3, destFile, 80);
		sprintf(cTemp, "Copy File Subroutine moved file %s to %s; fileListnum = %d", cTemp2, cTemp3, fileListNum);
		WriteLog(1,1,1, cTemp); 
	}
	time2 = GetTickCount();
	dwTemp = time2 - time1;
	sprintf(cTemp, "File Moves Done   Move Time = %d mSec", dwTemp);
	WriteLog(1,1,1, cTemp);
	sprintf(cTemp, "Battery Voltage = %8.2f counts\n", GetBatVoltage( 10 ));
	WriteLog(1,1,1, cTemp);
	if(powerDownUSB)
		SR_GPIOBit(107, 0);

	return 0;
}

int WINAPI WinMain(	HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
	int				fileCount,
					numWritten,
					USBWriteCount,
					ADSIOError,
					PU_USBFileNum;
	unsigned int*	pData = 0;
	uint			temperature;
	float			totalAcqTime,
					flashFileTime,
					sampleAcqTime;
	char			cTemp[200], cTemp2[200], cTemp3[200];
	DWORD			time1, time2, dwTemp;
	TCHAR			fileName[100],
					destFile[200];
	HWND			hWnd;
	FILE			*killFile;

	WriteLog(1, 1, 1, "McSTAR Acoustic Receiver Data Acq program");
	sprintf(cTemp, "Built %s %s\n\n",__DATE__,__TIME__);
	WriteLog(1, 1, 1, cTemp);
	
	WriteLog(1, 1, 1, "Sleeping while USB disk(s) enumerate");
	Sleep(1000);
	
//	Set division between program and object memory to maximize program/data memory data space
	SetSystemMemoryDivision( 0x100 );

	ADSIOError = LoadADSmartIOFunctions();
				 
	ReadConfig( configData );
//	SetPowerState( LOW_POWER );
	MapRegisters();
	InitPSP();
	InitGPIO();

	//Figure out when to power up/down the USB disk(s)
	sampleAcqTime = configData.numSamples / configData.sampleRate;
	flashFileTime = 0.1 + ((float)configData.numSamples / 500000.0);
	totalAcqTime = (float)configData.numFlashFiles * (sampleAcqTime + flashFileTime);
	if( (totalAcqTime / (float)configData.USBSpinUpTime) > 2.0)
	{
//		SR_GPIOBit(107, 0);
		powerDownUSB = TRUE;
		PU_USBFileNum = configData.numFlashFiles - (int)(ceil((configData.USBSpinUpTime / (sampleAcqTime + flashFileTime)) + 0.5) + 2);
	} else
	{
		SR_GPIOBit(107, 1);
		powerDownUSB = FALSE;
		PU_USBFileNum = -1;
	}
	SR_GPIOBit(107, 1);

	temperature = SIOReadTemperature();
//	RETAILMSG(1,(L" TestAvr: Temperature = %d \r\n", temperature));

	CheckMemory( "Before new assignment");
	pData = new unsigned int[configData.numSamples];
	CheckMemory( "After new assignment");

	fileListNum = 0;
	for(USBWriteCount=0; USBWriteCount<configData.USBWrites; USBWriteCount++)
	{
		for(fileCount=0; fileCount<configData.numFlashFiles; fileCount++)
		{
			if( (killFile = fopen("\\FlashFX Disk\\McSTAR\\killMcSTAR", "r")) != NULL)
				exit(-1);

			sprintf(cTemp, "Starting Sample Acq = %d samples",configData.numSamples);
			WriteLog(1,1,1, cTemp);
			time1 = GetTickCount();
//			dwReadSSP( pData, configData.numSamples );
			ReadSSPWriteCF( pData, configData.numSamples, fileName);
			wcscpy(fileList[fileListNum][fileCount], fileName);
			time2 = GetTickCount();
			dwTemp = time2 - time1;
			sprintf(cTemp, "Acq Done   Acquire Time = %d mSec", dwTemp);	
//			WriteLog(1,1,1, cTemp);
/*
			WriteLog(1,1,1, "Starting Flash Disk Write ");	
			time1 = GetTickCount();
			numWritten = WriteToFlash( pData, configData.numSamples, fileName );
			time2 = GetTickCount();
			wcscpy(fileList[fileCount], fileName);
			dwTemp = time2 - time1;

			wcstombs(cTemp2, fileList[fileCount], 80);
			sprintf(cTemp, "Wrote %d samples to %s; File Number = %d of %d  Write Time = %d mSec", \
				numWritten, cTemp2, fileCount + 1, configData.numFlashFiles, dwTemp);
			WriteLog(1,1,1, cTemp);
*/
			if(fileCount == PU_USBFileNum)
				SR_GPIOBit(107, 1);
		}

		if(1 == 0)
		{
			if (g_hCopyFileThread) 
			{
				while( (WaitForSingleObject(g_hCopyFileThread, 0x01000L) != 0x00000000L))
					WriteLog(1,1,1, "CopyFileThread didn't complete in time");
			}
			g_hCopyFileThread = CreateThread (NULL, 0, copyFileThread, (PVOID)fileListNum, 0, NULL);
			if(fileListNum == 0)
				fileListNum = 1;
			else 
				fileListNum = 0;
		}
		else
		{
			MoveFileCF2USB( (PVOID)fileListNum );
		}
	}
		


	delete [] pData;
	VirtualFree((PVOID)v_pClkRegs,0,MEM_RELEASE);
	VirtualFree((PVOID)SspRegPtr,0,MEM_RELEASE);
	VirtualFree((PVOID)GpioRegPtr,0,MEM_RELEASE);

//	SetPowerState( HIGH_POWER );
	return 0;
}

