#include <windows.h>
#include <ntdll.h>
#include <commdlg.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
#pragma comment(lib,"Comdlg32.lib"

int __cdecl Main(int argc,char *argv[])
{
	//vars for file path
	wchar_t wFullPath[MAX_PATH] = {0};
	wchar_t wFileName[MAX_PATH] = {0};
	wchar_t wFileExt[MAX_PATH] = {0};
	//var for storage of text..I know I should do a chunk at a time 
	//approach for this..but gimme a brake..this was hard enough.. :} 
	char ReadBuffer[MAX_PATH] = {0};
	//structure for GetOpenFileName()
	OPENFILENAME ofn = {0};
	//Handle to the selected file
	HANDLE hFile = 0;
	//var that stores the bytes read from the selected file
	ULONG BytesRead = 0;
	//string tokenize vars
	char *StrBuf = 0;
	char *InpBuf = 0;
	//var that hold the number of inputs that come with interpretting this data structure
	int NumInputs = 0;
	//interators and storage indexers
	int i = 0,x = 0;
	//vars for data testing storage and results
	float fData,tData = 0;
	float fResult = 0;
	float Inputs[100] = {0};
	//program run modifyier
	bool fRun = 0;
	wcout<<L"This is the solution for finding the average of a random set of values."<<endl;
	wcout<<L"Please select input file"<<endl;
	//set the storage to all 0's
	memset(&Inputs,0,sizeof(float)*100);
	//setup the structure for GetOpenFileName
	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hwndOwner = NULL;
	ofn.lpstrFile = wFullPath;
	ofn.lpstrFile[0] = '\0';
	ofn.nMaxFile = sizeof( wFullPath );
	ofn.lpstrFilter = L"Text\0*.TXT\0";
	ofn.nFilterIndex =1;
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	ofn.lpstrInitialDir=NULL;
	ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST;
	//http://msdn.microsoft.com/en-us/library/ms646927(VS.85).aspx
	GetOpenFileName(&ofn);
	//http://msdn.microsoft.com/en-us/library/e737s6tf.aspx
	_wsplitpath(wFullPath,0,0,wFileName,wFileExt);
	wcout<<wFileName<<wFileExt<<L" selected"<<endl;
	wcout<<L"Beginning processing of file."<<endl;
	wcout<<L"Now validating file structure."<<endl;
	//http://msdn.microsoft.com/en-us/library/bb540534(VS.85).aspx
	//Open the selected file
	hFile = CreateFile(wFullPath,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
	if(hFile == INVALID_HANDLE_VALUE)
	{
		wcout<<L"Failed to open file.."<<endl;
		return 1;
	}
	//Read the file into ReadBuffer
	if(ReadFile(hFile,ReadBuffer,MAX_PATH,&BytesRead,0) == FALSE)
	{
		wcout<<L"Failed to read file.."<<endl;
		CloseHandle(hFile);
		return 2;
	}
	//test if we read anything
	if(BytesRead > 0)
	{
		//http://msdn.microsoft.com/en-us/library/zkx076cy(VS.80).aspx
		if(!sscanf(ReadBuffer,"%d",&NumInputs))
		{
			wcout<<L"Failed Validation"<<endl;
			return 3;
		}
		if(NumInputs > 98)
		{
			wcout<<L"Inputs to high"<<endl;
			return 4;
		}
		wcout<<L"Successful Validation of File Structure."<<endl;
		wcout<<L"Number of Inputs:"<<NumInputs<<endl;
		wcout<<L"Begin parsing of file data."<<endl;
		//http://msdn.microsoft.com/en-us/library/z9da80kz(VS.80).aspx
		//get past the first carriage return and newline separators. 
		StrBuf = strstr(ReadBuffer,"\r\n"

;
		//http://msdn.microsoft.com/en-us/library/2c8d19sb(VS.71).aspx
		//tokenize the string to separate out the data 
		InpBuf = strtok(StrBuf,"\r\n"

;
Digest:
		//make sure result = 0 so no tainting occurs..(bug #3)
		fResult = 0;
		for(i = 0;i<NumInputs;i++)
		{
			if(!fRun)
			{
				//change the ascii to floats(really doubles..)
				Inputs[I] = atof(InpBuf);
			}
			//add up the result and check for -1 that signifies faulty data.
			fResult += Inputs[I] != -1 ? Inputs[I] : 0;
			if(!fRun)
			{
				wcout<<L"Data["<<i<<L"]"<<L" = "<<Inputs[I]<<endl;
				//get next tokenized string part
				InpBuf = strtok(NULL,"\r\n"

;
			}
		}
		if(!fRun)
		{
			//caclulate the prelimanary result added 
			//up result divided by the number of inputs
			fResult = fResult/NumInputs;
			wcout<<L"Prelimanary  average result: "<<fResult<<endl;
			wcout<<L"Scanning array for faulty data"<<endl;
			i = 0;
			//x equals NumInputs + 1 because we want 2 unused areas
			x = NumInputs + 1;
			do
			{
				//check storage for current farthest value
				if(Inputs[x - 1] == 0)
				{
					//calculate the proper subtraction sequence
					fData = Inputs[I] > fResult ? Inputs[I] - fResult : fResult - Inputs[I];
				}
				else
				{
					//set fData to current farthest value..(unneeded..but w/e) 
					fData = Inputs[x - 1];
				}
				//increment i to calculate next subtraction sequence
				i++;
				tData = Inputs[I] > fResult ? Inputs[I] - fResult : fResult - Inputs[I];
				//if current fData > tData and i == 1 the index of fData = i - 1 or 0..
				if(fData > tData && i == 1)
				{
					Inputs[x] = i - 1;
					//store the fartherest data in NumInputs or x - 1..for all those following..
					Inputs[x - 1] = fData;
				}
				//blah blah blah see above adjust as seen below ;p
				if(tData > fData)
				{
					Inputs[x] = i;
					Inputs[x - 1] = tData;
				}
			}while(i < NumInputs -1);
			i = Inputs[x];
			wcout<<L"Faulty data: "<<Inputs[I]<<L" Index:"<<i<<endl;
			wcout<<L"Modifying faulty data."<<endl;
			Inputs[I] = -1;
			fRun++;
			goto Digest;
		}
		else
		{   
			//calculate the final result,
			//Result = sum of array divided by NumInputs - 1 
			//to account for the removed data..
			fResult = fResult/(NumInputs - 1);
			wcout<<L"Final average result: "<<fResult<<endl;
		}
	}
	wcout<<L"Finished"<<endl;
	CloseHandle(hFile);
	return 0;
}