#include "StdAfx.h"
#include "Global.h"

#define VLEN 10

namespace GLOBAL
{
	TCHAR g_szModulePath[MAX_PATH] = _T("");			// 软件目录;
	TCHAR g_szModuleFileName[MAX_PATH] = _T("");		// 软件名称;

	void Init()
	{
		TCHAR szDrive[_MAX_DRIVE] = { 0 };
		TCHAR szDir[_MAX_DIR] = { 0 };
		TCHAR szFna[_MAX_DIR] = { 0 };
		TCHAR szExt[_MAX_DIR] = { 0 };
		::GetModuleFileName(NULL, g_szModulePath, sizeof(g_szModulePath) / sizeof(TCHAR));
		_stprintf_s(g_szModuleFileName, _T("%s"), g_szModulePath);

		_tsplitpath_s(g_szModulePath, szDrive, szDir, szFna, szExt);
		_tcscpy_s(g_szModulePath, szDrive);
		_tcscat_s(g_szModulePath, szDir);
	}

	// 调用批处理,返回的是多字节字符;
	BOOL StartProcess(LPCTSTR lpApplicationName, LPCTSTR lpCommandLine, CString &strStdOutput)
	{	
		HANDLE hRead,hWrite;  
		SECURITY_ATTRIBUTES sa;  		
		sa.nLength = sizeof(SECURITY_ATTRIBUTES);  
		sa.lpSecurityDescriptor = NULL; //使用系统默认的安全描述符  
		sa.bInheritHandle = TRUE; //创建的进程继承句柄

		if (!CreatePipe(&hRead,&hWrite,&sa,0)) //创建匿名管道  
		{  
			MessageBox(NULL, _T("CreatePipe Failed!"), _T("提示"), MB_OK | MB_ICONWARNING);  
			return FALSE;  
		}  

		STARTUPINFO si;  
		PROCESS_INFORMATION pi;  
		ZeroMemory(&si,sizeof(STARTUPINFO)); 
		si.cb = sizeof(STARTUPINFO);  
		GetStartupInfo(&si);  
		si.hStdError = hWrite;  
		si.hStdOutput = hWrite; //新创建进程的标准输出连在写管道一端  
		si.wShowWindow = SW_HIDE; //隐藏窗口  
		si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;  
		//si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);

		TCHAR szCommandLine[MAX_PATH] = {0};
		if ( lpCommandLine ) _stprintf_s(szCommandLine, _T("%s"), lpCommandLine);
		if (!CreateProcess(lpApplicationName, lpCommandLine ? szCommandLine : NULL, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) //创建子进程  
		{  
			MessageBox(NULL, _T("CreateProcess Failed!"), _T("提示"), MB_OK | MB_ICONWARNING);  
			return FALSE;  
		}  

		dprintf("进程ID=%ld", pi.dwProcessId);
		// 等待进程完成退出.
		WaitForSingleObject(pi.hProcess,INFINITE);	

		CloseHandle(hWrite); //关闭管道句柄  

		TCHAR szBuffer[4096] = {0};  
		DWORD bytesRead;  
		while (true)
		{  
			if (ReadFile(hRead,szBuffer,4096*sizeof(TCHAR),&bytesRead,NULL) == NULL) //读取管道  
				break;  
			strStdOutput += szBuffer;  
			Sleep(100);  
		}  
		dprintf("输出内容=%s", strStdOutput.GetString());
		CloseHandle(hRead); 

		return TRUE;
	}

	CString ReadFileContent(LPCTSTR lpFileName)
	{
		CString strData = _T("");
		if ( !lpFileName || !PathFileExists(lpFileName) )
			return strData;

		CFile file;
		CFileException exp;
		std::string strRead;
		if ( file.Open(lpFileName, CFile::modeRead, &exp) )
		{
			DWORD dwRead = 0;
			DWORD dwCount = 0;
			
			TCHAR szRead[MAX_PATH] = {0};
			DWORD dwLen = file.GetLength();
			while ( dwCount = file.Read(szRead, MAX_PATH) )
			{
				strRead.append(szRead, dwCount);
			}

			file.Close();
		}

		return CString(strRead.c_str());
	}

	void GetStringList(CString strData, CString strSplit, CStringList &ListStr)
	{
		int nPos = -1;
		CString strTemp;
		ListStr.RemoveAll();
		do 
		{
			nPos = strData.Find(strSplit);
			if ( nPos != -1 )
			{
				strTemp = strData.Mid(0, nPos);
				ListStr.AddTail(strTemp);
				strData = strData.Mid(nPos+strSplit.GetLength());
			}
		} while (nPos != -1);
	}

	BOOL FindString(CStringList &ListStr, CString strFind, CString &strResult)
	{
		CString strTemp;
		POSITION pos = ListStr.GetHeadPosition();
		while (pos != NULL)
		{
			strTemp = ListStr.GetNext(pos);
			if ( strTemp.Find(strFind) != -1 )
			{
				strResult = strTemp;
				return TRUE;
			}
		}

		return FALSE;
	}

	INT CheckListData(CStringList &listStr)
	{
		INT nPassCount = 0;
		INT nCount = listStr.GetSize();
		if ( nCount == 0 ) return nPassCount;

		CString strLevel = _T(""), strDist = _T("");
		POSITION pos = listStr.GetHeadPosition();
		while (pos != NULL)
		{
			strDist = listStr.GetNext(pos);
			if ( pos == NULL ) 
				return nPassCount;
			strLevel = listStr.GetNext(pos);

			TCHAR szDist[5][VLEN] = {0};
			TCHAR szLevel[5][VLEN] = {0};

			if (_stscanf_s(strDist.GetString(), _T("%*[^=]=%[^,],%[^,],%[^,],%[^,],%s"), szDist[0], VLEN, szDist[1], VLEN, szDist[2], VLEN, szDist[3], VLEN, szDist[4], VLEN) == 5 )
			{
				if (_stscanf_s(strLevel.GetString(), _T("%*[^=]=%[^,],%[^,],%[^,],%[^,],%s"), szLevel[0], VLEN, szLevel[1], VLEN, szLevel[2], VLEN, szLevel[3], VLEN, szLevel[4], VLEN) == 5 )
				{
					std::bitset<5> bitDist(0);
					std::bitset<5> bitLevel(0);

					int nValue = 0;
					for ( int i = 0; i < 5; i++ )
					{
						nValue = _tstoi(szDist[i]);
						bitDist[i] = (nValue > 80 && nValue < 130) ? 1 : 0;

						nValue = _tstoi(szLevel[i]);
						bitLevel[i] = (nValue > 25) ? 1 : 0;
					}

					
					int nDistValue = bitDist.to_ulong();
					int nLevelValue = bitLevel.to_ulong();
					if ( (nDistValue & nLevelValue) > 0 )
					{
						nPassCount++;
						dprintf("PASS");
					}
					else
					{
						dprintf(_T("dist=[%s][%s][%s][%s][%s],[%s],[%ld]"), szDist[0],szDist[1],szDist[2],szDist[3],szDist[4], bitDist.to_string().c_str(), bitDist.to_ulong());
						dprintf(_T("level=[%s][%s][%s][%s][%s],[%s],[%ld]"), szLevel[0],szLevel[1],szLevel[2],szLevel[3],szLevel[4], bitLevel.to_string().c_str(), bitLevel.to_ulong());

						dprintf("FAIL,%s,%s", bitDist.to_string().c_str(), bitLevel.to_string().c_str());
					}
				}
				else
				{
					dprintf("失败：%s", strLevel.GetString());
				}
			}
			else
			{
				dprintf("失败：%s", strDist.GetString());
			}
		}

		return nPassCount;
	}

	BOOL SaveList(CStringList &ListStr)
	{
		CFile file;
		INT nMark = 0;
		CFileException exp;
		TCHAR szSaveFile[MAX_PATH] = {0};
		_stprintf_s(szSaveFile, _T("%s%s"), GLOBAL::g_szModulePath, _T("result.csv"));
		if ( !PathFileExists(szSaveFile) )
			nMark = 1;
		if ( file.Open(szSaveFile, CFile::modeCreate|CFile::modeWrite, &exp) )
		{
			file.SeekToBegin(); 

			CString strValue = _T("DSN,Log,Percent,Result\r");
			file.Write(strValue.GetString(), strValue.GetLength()*sizeof(TCHAR));
			POSITION pos = ListStr.GetHeadPosition();
			while (pos != NULL)
			{
				strValue = ListStr.GetNext(pos) + _T("\r");
				file.Write(strValue.GetString(), strValue.GetLength()*sizeof(TCHAR));
			}

			file.Flush();   
			file.Close();   
			return TRUE;
		}

		return FALSE;
	}

	static INT CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM pData)
	{
		switch (uMsg)
		{
		case BFFM_INITIALIZED:
			SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)GLOBAL::g_szModulePath);
			break;
		case BFFM_SELCHANGED:
			{
				TCHAR szFileName[MAX_PATH];
				LPITEMIDLIST pidlCurrent = (LPITEMIDLIST)lp;
				SHGetPathFromIDList(pidlCurrent, szFileName);
				SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)szFileName);
			}
			break;
			// 这个不能让默认目录为桌面;
			// 	case BFFM_INITIALIZED:
			// 		{
			// 			// WParam is TRUE since you are passing a path.
			// 			// It would be FALSE if you were passing a pidl.
			// 			TCHAR szDir[MAX_PATH] = { 0 };
			// 			GetCurrentDirectory(sizeof(szDir) / sizeof(TCHAR), szDir);
			// 			SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)szDir);
			// 		}
			// 		break;
		}
		return 0;
	}

	BOOL GetFilePath(OUT TCHAR *FilePath, IN HWND hParentWnd, IN TCHAR* InstructionString, IN UINT ulFlags)
	{
		BROWSEINFO bInfo;
		LPITEMIDLIST pidl, pidlDesktop;
		ZeroMemory((PVOID)&bInfo, sizeof(BROWSEINFO));

		HRESULT hr = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidlDesktop);
		if ( hr != S_OK )
		{
			return FALSE;
		}

		bInfo.pidlRoot = pidlDesktop;
		bInfo.hwndOwner = hParentWnd;
		bInfo.pszDisplayName = FilePath;
		bInfo.lpszTitle = InstructionString;
		bInfo.ulFlags = ulFlags;
		bInfo.lpfn = BrowseCallbackProc;
		bInfo.lParam = 0;

		if ((pidl = ::SHBrowseForFolder(&bInfo)) == NULL)    
		{
			return FALSE;
		}

		if (::SHGetPathFromIDList(pidl, FilePath) == FALSE)   
		{
			return FALSE;
		}

		return TRUE;
	}
};
