#include "pch.h"
#include "findfile.h"
#include <algorithm>

// 查找文件的最大数量限制在nMaxLimit;
CONST size_t nMaxLimit = 0xFFFFFFFF;	//--4294967295;
// 查找文件的默认数量限制在nDefLimit;
CONST size_t nDefLimit = 0xFFFFF;	//--1048575

// 路径分隔符;
CONST TCHAR		c_pathSeparator = _T('\\');
CONST TString	s_pathSeparator = _T("\\");
CONST TString	g_sVertical = _T("|");

// 正确的扩展名及格式样列;
// 这个值最好可以从配置文件ini或xml中获取,不用在代码里写死;
CONST TString	g_sCorrectExt = _T("*.jpg|*.jpeg|*.png|*.bmp|*.cr2|*.nef|*.raw");


findfile::findfile(void):
m_nlimit(nDefLimit),
m_pvtfiles(NULL),
m_pvtnames(NULL),
m_pvtfolders(NULL),
m_pvtfiles_sth(NULL),
m_pvtfiles_mth(NULL)
{
	
}

findfile::~findfile(void)
{
}

/************************************************************************/
/*
函数:match
描述:判断指定的文件命名是否匹配指定的扩展名;
参数:
IN	sFileExt	扩展名;
IN	sFile		文件名;
返回:匹配返回非0值,否则返回0;
注意:
*/
/************************************************************************/
void findfile::setlimit(IN CONST INT &nLimit)
{
	if (nLimit < 1)
		m_nlimit = nDefLimit;
	if (nLimit < nMaxLimit)
		m_nlimit = nLimit;
}

// 获取文件名;
TString findfile::getfilename(IN CONST TString &file)
{
	TString name;
	TString strfile = file;
	int nIndex = strfile.find_last_of(_T('\\'));	// 如果file不包含 '\\' ,得不到文件名;
	if (nIndex == TString::npos)
	{
		nIndex = strfile.find_last_of(_T('.'));
		if ( nIndex == TString::npos )
			return _T("");

		return strfile.substr(0, nIndex);
	}

	name = strfile.substr(nIndex+1);
	nIndex = name.find_last_of(_T('.'));
	if (nIndex == TString::npos)
		return _T("");

	return name.substr(0, nIndex);
}

void findfile::find1st(TString folder, TString &file)
{
	TString path = folder;
	if (path.size() > 0 && c_pathSeparator != path[path.size() - 1])
		path.append(s_pathSeparator);

	TString _file = _T("*");
	TString s = path + _file;

	WIN32_FIND_DATA fileinfo = { 0 };
	HANDLE handle = FindFirstFile(s.c_str(), &fileinfo);

	if (NULL != handle && INVALID_HANDLE_VALUE != handle)
	{
		do
		{
			// '.'和 '..'的系统文件去除;
			if (_T('.') != fileinfo.cFileName[0])
			{
				if ((FILE_ATTRIBUTE_DIRECTORY & fileinfo.dwFileAttributes) != FILE_ATTRIBUTE_DIRECTORY)	// 目录;
				{
					file = path + fileinfo.cFileName;
					break;
				}
			}
		} while (FindNextFile(handle, &fileinfo));

		FindClose(handle);
	}
}

// 全部;
void findfile::findall(IN CONST TString& folder)
{
	TString path = folder;
	if (path.size() > 0 && c_pathSeparator != path[path.size() - 1])
		path.append(s_pathSeparator);

	TString file = _T("*");
	TString s = path + file;

	WIN32_FIND_DATA fileinfo = { 0 };
	HANDLE handle = FindFirstFile(s.c_str(), &fileinfo);

	if (NULL != handle && INVALID_HANDLE_VALUE != handle)
	{
		do
		{
			// 检查是否超过最大数;
			if (checklimit()) break;

			// '.'和 '..'的系统文件去除;
			if (_T('.') != fileinfo.cFileName[0])
			{
				if ((FILE_ATTRIBUTE_DIRECTORY & fileinfo.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY)	// 目录;
				{
					m_pvtfolders->push_back(path + fileinfo.cFileName);
					findall(path + fileinfo.cFileName);
				}
				else
				{
					if (!checklimit())
					{
						m_pvtnames->push_back(fileinfo.cFileName);
						m_pvtfiles->push_back(path + fileinfo.cFileName);
					}
				}
			}

		} while (FindNextFile(handle, &fileinfo));

		FindClose(handle);
	}
}

void findfile::findsubfolder(IN CONST TString& folder)	// 查找子目录;
{
	TString path = folder;
	if (path.size() > 0 && c_pathSeparator != path[path.size() - 1])
		path.append(s_pathSeparator);

	TString file = _T("*");
	TString s = path + file;

	WIN32_FIND_DATA fileinfo = { 0 };
	HANDLE handle = FindFirstFile(s.c_str(), &fileinfo);

	if (NULL != handle && INVALID_HANDLE_VALUE != handle)
	{
		do
		{
			if (_T('.') != fileinfo.cFileName[0])// '.'和 '..'的系统文件去除;
			{
				if ((FILE_ATTRIBUTE_DIRECTORY & fileinfo.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY)	// 目录;
				{
					m_pvtfolders->push_back(path + fileinfo.cFileName);
				}
			}
		} while (FindNextFile(handle, &fileinfo));

		FindClose(handle);
	}
}

void findfile::findallsubfolder(IN CONST TString& folder)
{
	TString path = folder;
	if (path.size() > 0 && c_pathSeparator != path[path.size() - 1])
		path.append(s_pathSeparator);

	TString file = _T("*");
	TString s = path + file;

	WIN32_FIND_DATA fileinfo = { 0 };
	HANDLE handle = FindFirstFile(s.c_str(), &fileinfo);

	if (NULL != handle && INVALID_HANDLE_VALUE != handle)
	{
		do
		{
			if (_T('.') != fileinfo.cFileName[0])// '.'和 '..'的系统文件去除;
			{
				if ((FILE_ATTRIBUTE_DIRECTORY & fileinfo.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY)	// 目录;
				{
					m_pvtfolders->push_back(path + fileinfo.cFileName);
					findallsubfolder(path + fileinfo.cFileName); // 不入子目录查找;
				}
			}
		} while (FindNextFile(handle, &fileinfo));

		FindClose(handle);
	}
}

//////////////////////////////////////////////////////////////////////////
void findfile::findfiles_findin_subfolder(IN CONST TString& folder)
{
	TString path = folder;
	if (path.size() > 0 && c_pathSeparator != path[path.size() - 1])
		path.append(s_pathSeparator);

	TString file = _T("*");
	TString s = path + file;

	WIN32_FIND_DATA fileinfo = { 0 };
	HANDLE handle = FindFirstFile(s.c_str(), &fileinfo);

	if (NULL != handle && INVALID_HANDLE_VALUE != handle)
	{
		do
		{
			// 检查是否超过最大数;
			if (checklimit()) break;

			// '.'和 '..'的系统文件去除;
			if (_T('.') != fileinfo.cFileName[0])
			{
				if ((FILE_ATTRIBUTE_DIRECTORY & fileinfo.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY)	// 目录;
				{
					findfiles_findin_subfolder(path + fileinfo.cFileName);
				}
				else
				{
					if (!checklimit())
					{
						m_pvtfiles->push_back(path + fileinfo.cFileName);
					}
				}
			}
		} while (FindNextFile(handle, &fileinfo));

		FindClose(handle);
	}
}

void findfile::findfiles_findout_subfolder(IN CONST TString& folder)
{
	TString path = folder;
	if (path.size() > 0 && c_pathSeparator != path[path.size() - 1])
		path.append(s_pathSeparator);

	TString file = _T("*");
	TString s = path + file;

	WIN32_FIND_DATA fileinfo = { 0 };
	HANDLE handle = FindFirstFile(s.c_str(), &fileinfo);

	if (NULL != handle && INVALID_HANDLE_VALUE != handle)
	{
		do
		{
			// 检查是否超过最大数;
			if (checklimit()) break;

			// '.'和 '..'的系统文件去除;
			if (_T('.') != fileinfo.cFileName[0])
			{
				if ((FILE_ATTRIBUTE_DIRECTORY & fileinfo.dwFileAttributes) != FILE_ATTRIBUTE_DIRECTORY)	// 目录;
				{
					if (!checklimit())
					{
						m_pvtfiles->push_back(path + fileinfo.cFileName);
					}
				}
			}
		} while (FindNextFile(handle, &fileinfo));

		FindClose(handle);
	}
}

void findfile::findfiles_within_subfolder(IN CONST TString& folder)
{
	TString path = folder;
	if (path.size() > 0 && c_pathSeparator != path[path.size() - 1])
		path.append(s_pathSeparator);

	TString file = _T("*");
	TString s = path + file;

	WIN32_FIND_DATA fileinfo = { 0 };
	HANDLE handle = FindFirstFile(s.c_str(), &fileinfo);

	if (NULL != handle && INVALID_HANDLE_VALUE != handle)
	{
		do
		{
			// 检查是否超过最大数;
			if (checklimit()) break;

			// '.'和 '..'的系统文件去除;
			if (_T('.') != fileinfo.cFileName[0])
			{
				if ((FILE_ATTRIBUTE_DIRECTORY & fileinfo.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY)	// 目录;
				{
					m_pvtfolders->push_back(path + fileinfo.cFileName);
					findfiles_within_subfolder(path + fileinfo.cFileName);
				}
				else
				{
					if (!checklimit())
					{
						m_pvtfiles->push_back(path + fileinfo.cFileName);
					}
				}
			}
		} while (FindNextFile(handle, &fileinfo));

		FindClose(handle);
	}
}
