/*
	CDir
	ディレクトリ関係の処理を行う
	インプリメンテーション ファイル

	Version		: 0.0 (Release1)
	Version		: 0.0 (Release1)
	説明		: ファイルの検索やパスの処理など


	作成日		: 2000/12/07
	修正日		: ----/--/--
	改定履歴	: 
*/

#include "stdafx.h"
#include "Dir.h"

#include <direct.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// 構築/消滅
//////////////////////////////////////////////////////////////////////

CDir::CDir()
{
	m_fileList.RemoveAll();
}


CDir::~CDir()
{

}

//////////////////////////////////////////////////////////////////////
// パス名変換
//////////////////////////////////////////////////////////////////////
/*
	関数名		: CDir::PathToName(CString path)
	処理内容	: パスからファイル名を取得
	引数		: パス
	帰り値		: ファイル名
*/
CString CDir::PathToName(CString path)
{
	int	index;

	index = path.ReverseFind('\\');
	if(index==-1)
		return(path);

	return(path.Right(path.GetLength() - index - 1));
}

/*
	関数名		: CDir::PathToDir(CString path)
	処理内容	: パスからファイル名を削除
	引数		: パス
	帰り値		: パス
*/
CString CDir::PathToDir(CString path)
{
	int	index;

	index = path.ReverseFind('\\');
	if(index==-1)
		return("");

	path = path.Left(index);
	path = AddBackSlash(path);

	return(path);
}

/*
	関数名		: CDir::PathToDir(CString path)
	処理内容		: パスから拡張子を取得
	引数			: パス
	帰り値		: パス
*/
CString CDir::PathToExt(CString path)
{
	int	index;

	index = path.ReverseFind('.');
	if(index==-1)
		return(path);

	return(path.Right(path.GetLength() - index - 1));
}



//////////////////////////////////////////////////////////////////////
// ディレクトリ生成
//////////////////////////////////////////////////////////////////////
/*
	関数名		: CDir::MakeDirectory(CString path)
	処理内容	: ディレクトリの生成
	引数		: パス
	帰り値		: -1：エラー、0：すでに存在、1：生成に成功
*/
int CDir::MakeDirectory(CString path)
{
	CFileFind	find;

	while(1)
	{
		if(CheckBackSlash(path) || CheckLastChar(path,' '))
		{
			path=path.Left(path.GetLength()-1);
		}
		else
		{
			break;
		}
	}

	path=path+"\\";

	if(!find.FindFile(path + "*.*"))
	{
		find.Close();
		if(_mkdir(path)==-1)
			return(-1);
		return(1);
	}
	find.Close();

	return(0);
}


/*
	関数名		: CDir::MakeAllDirectory(CString path)
	処理内容	: パスに存在するディレクトリを全て生成
	引数		: パス
	帰り値		: -1：エラー、0：生成に成功
*/
int CDir::MakeAllDirectory(CString path)
{
	CString	mpath;
	int	i,ret=0;

	path = AddBackSlash(path);

	while(1)
	{
		i=path.Find("\\");
		if(i==-1)
			break;
		mpath = mpath + path.Left(i+1);
		path = path.Right(path.GetLength() - i - 1);
//		if(MakeDirectory(mpath)==-1)
//			return(-1);

		//	ネットワークドライブ対策
		ret = MakeDirectory(mpath);
	}
	return(ret);
}


//////////////////////////////////////////////////////////////////////
// ファイルの検索
//////////////////////////////////////////////////////////////////////
/*
	関数名		: CDir::FindFile(CString path, int subDirectory)
	処理内容	: ファイルの検索
	引数		: path : パス(C:\*.jpg・・・)、subDirectory : 1:サブディレクトリも有効
	帰り値		: -1：エラー、0：成功
*/
int CDir::FindFile(CString path, int subDirectory)
{
	int				done=1;
	CFileFind		find;

	m_allFileSize = 0;

	if(find.FindFile(path))
	{
		while(done)
		{
			done=find.FindNextFile();

			if(find.IsDots())
				continue;

			//	再起検索
			if(find.IsDirectory())
			{
				if(subDirectory)
				{
					double push = m_allFileSize;
					FindFile(find.GetFilePath() + "\\" + PathToName(path),subDirectory);
					m_allFileSize += push;
				}
				continue;
			}
			
			//	警告が出るから・・・
			CString	add = find.GetFilePath();
			m_fileList.Add(add);
			m_allFileSize += find.GetLength();
		}
	}
	find.Close();
	
	return(0);
}


/*
	関数名		: CDir::FindDir(CString path)
	処理内容	: ディレクトリの検索
	引数		: path : パス(C:\*.jpg・・・)
	帰り値		: -1：エラー、0：成功
*/
int CDir::FindDir(CString path)
{
	int			done=1;
	CFileFind		find;

	if(find.FindFile(path))
	{
		while(done)
		{
			done=find.FindNextFile();

			if(find.IsDots())
				continue;

			//	再起検索
			if(find.IsDirectory())
			{
				FindDir(find.GetFilePath() + "\\" + PathToName(path));

				//	警告が出るから・・・
				CString	add = find.GetFilePath();
				m_fileList.Add(add);
			}			
		}
	}
	find.Close();
	
	return(0);
}


/*
	関数名		: CDir::GetFileCount()
	処理内容	: 見つかったファイル数を返す
	引数		: なし
	帰り値		: ファイル数
*/
int CDir::GetFileCount()
{
	return((int)m_fileList.GetSize());
}


/*
	関数名		: CDir::GetFilePath(int index)
	処理内容	: 見つかったファイルのパスを返す
	引数		: インデックス
	帰り値		: ファイルパス
*/
CString CDir::GetFilePath(int index)
{
	return(m_fileList.GetAt(index));
}


//////////////////////////////////////////////////////////////////////
// ディレクトリの日付を取得
//////////////////////////////////////////////////////////////////////
/*
	関数名		: CDir::GetDirectoryDate(CString path)
	処理内容	: ディレクトリの日付を取得
	引数		: path : パス
	帰り値		: -1：エラー、0：成功
*/
int CDir::GetDirectoryDate(CString path,CTime &time)
{
	CFileFind	find;
	int			done=1;

	path = RemoveBackSlash(path);

	if(find.FindFile(path))
	{
		while(done)
		{
			done=find.FindNextFile();

			if(find.IsDots())
				continue;

			if(find.IsDirectory())
			{
				find.GetCreationTime(time);
				find.Close();				
				return(0);
			}			
		}

		find.Close();				
		return(-1);
	}
	else
	{
		find.Close();
		return(-1);
	}
}

double CDir::GetAllFleSize()
{
	return m_allFileSize;
}


//!	ファイルもしくはディレクトリが存在するか
/*!
	CDirectoryUtility::FILE_TYPE_FILE		ファイルが存在
	CDirectoryUtility::FILE_TYPE_DIRECTORY	フォルダが存在
	CDirectoryUtility::FILE_TYPE_NOTFOUND	なし
*/
int CDir::FileExist(CString path)
{
	CFileFind	find;

	//	ディレクトリ
	if(CheckBackSlash(path))
	{
		path += "*.*";
		if(find.FindFile(path))
			return(FILE_TYPE_DIRECTORY);
	}

	//	ファイル
	if(find.FindFile(path))
	{
		find.FindNextFile();
		if(find.IsDirectory())
			return(FILE_TYPE_DIRECTORY);

		//	システムデバイス？
		if(find.GetFilePath().Left(4) == "\\\\.\\")
			return(FILE_TYPE_NOTFOUND);

		CString	srcPath = CDir::PathToName(path);
		CString	destPath = find.GetFileName();
		if(srcPath.CompareNoCase(destPath) == 0)
			return(FILE_TYPE_FILE);
	}

	//	ディレクトリ2
	if(find.FindFile(path + _T("\\*.*")))
	{
		return(FILE_TYPE_DIRECTORY);
	}

	return(FILE_TYPE_NOTFOUND);
}

//!	ファイルもしくはディレクトリの属性取得
int CDir::GetFileAttribute(CString path)
{
	path = RemoveBackSlash(path);

	CFileStatus	stat;
	if(CFile::GetStatus(path,stat))
	{
		return(stat.m_attribute);
	}
	else
		return(-1);
}


//!	スラッシュを後ろに追加
CString CDir::AddSlash(CString path)
{
	if(CheckSlash(path))
		return(path);

	return(path + "/");
}

//!	バックスラッシュを後ろに追加
CString CDir::AddBackSlash(CString path)
{
	if(CheckSlash(path) || CheckBackSlash(path))
		return(path);

	return(path + "\\");
}

//!	スラッシュを後ろから削除
CString CDir::RemoveSlash(CString path)
{
	if(CheckSlash(path))
		path = path.Left(path.GetLength()-1);

	return(path);
}

//!	バックスラッシュを後ろから削除
CString CDir::RemoveBackSlash(CString path)
{
	if(CheckBackSlash(path))
		path = path.Left(path.GetLength()-1);

	return(path);
}

//!	最後の文字をチェック
int CDir::CheckLastChar(CString path,unsigned char c)
{
	unsigned char	*ptr = (unsigned char*)path.GetBuffer(path.GetLength() + 10);

	//	空文字列
	if(*ptr == 0)
		return(0);

	while(1)
	{
		//	シングルバイト
		if(*ptr <= 0x80 || (*ptr >= 0xA0 && *ptr <= 0xDF))
		{
			//	終了?
			if(*(ptr+1) == 0)
			{
				if(*ptr == c)
					return(1);
				else
					return(0);
			}
			ptr++;
		}
		else
		{
			//	終了?
			if(*(ptr+1) == 0 || *(ptr+2) == 0)
				return(0);
			ptr+=2;
		}
	}
}

//!	最後にスラッシュがあるか
int CDir::CheckSlash(CString path)
{
	return(CheckLastChar(path,'/'));
}

//!	最後にスラッシュがあるか
int CDir::CheckBackSlash(CString path)
{
	return(CheckLastChar(path,'\\'));
}

//!	ひとつ上のディレクトリパスを取得
CString CDir::GetUpDir(CString path)
{
	int index = path.ReverseFind('\\');
	if(index == -1)
		return(path);

	return(path.Mid(0,index));
}
