Imports System.Collections.Generic

Namespace System
Namespace IO

/*!
@brief	ディレクトリの情報を取得したり操作するクラス
*/

Class Directory
Public

	'----------------------------------------------------------------
	' パブリック メソッド
	'----------------------------------------------------------------

	/*!
	@brief	ディレクトリを作成する
	@param  作成するディレクトリのファイルパス
	@return 作成されたディレクトリのDirctoryInfo
	*/
	Static Function CreateDirectory(path As String) As DirectoryInfo
		Dim info = New DirectoryInfo(path)
		info.Create()
		Return info
	End Function

	/*
	Static Function CreateDirectory(path As String, directorySecurity As DirectorySecurity) As DirectoryInfo
	End Function */

	/*!
	@brief	ディレクトリを削除する
	ディレクトリが開き出ない場合は削除されない
	@param  消去するディレクトリのファイルパス
	*/
	Static Sub Delete(path As String)
		Dim info = New DirectoryInfo(path)
		info.Delete()
	End Sub

	/*!
	@brief	ディレクトリを削除する
	@param  削除するディレクトリのファイルパス
	@param  ディレクトリの中身も消去する場合True
	*/
	Static Sub Delete(path As String, recursive As Boolean)
		Dim info = New DirectoryInfo(path)
		info.Delete(recursive)
	End Sub

	/*!
	@brief	ディレクトリが存在するかどうか
	@param  調べるディレクトリのファイルパス
	@retval True  存在する
	@retval False 存在しない
	*/
	Static Function Exists(path As String) As Boolean
		Dim info = New DirectoryInfo(path)
		Return info.Exists
	End Function

	/*!
	@brief	カレントディレクトリを取得する
	@return カレントディレクトリを示すパス
	*/
	Static Function GetCurrentDirectory() As String
		Return System.Environment.CurrentDirectory
	End Function

	/*
	Static Function GetAccessControl(path As String) As DirectorySecurity
	End Function

	Static Function GetAccessControl(path As String, includeSections As System.Security.AccessControl.AccessControlSections) As DirectorySecurity
	End Function
	*/

	/*!
	@brief	ディレクトリの作成日を取得する
	@param  ディレクトリを示すパス
	@return 作成日
	*/
	Static Function GetCreationTime(path As String) As DateTime
		Dim info = New DirectoryInfo(path)
		Return info.CreationTime
	End Function

	/*!
	@brief	ディレクトリの作成日をUTC時刻で取得する
	@param  ディレクトリを示すパス
	@return 作成日(UTC)
	*/
	Static Function GetCreationTimeUtc(path As String) As DateTime
		Dim info = New DirectoryInfo(path)
		Return info.CreationTimeUtc
	End Function

	/*!
	@brief	ディレクトリ内のディレクトリを列挙する
	@param  中身を調べるディレクトリのパス
	@return ディレクトリのパス文字列が列挙された配列
	*/
	Static Function GetDirectories(path As String) As List<String>
		Return GetDirectories(path, "?*", SearchOption.TopDirectoryOnly)
	End Function

	/*!
	@brief	ディレクトリ内のディレクトリを列挙する
	@param  中身を調べるディレクトリのパス
	@param  サーチするディレクトリ名のパターン
	@return ディレクトリのパス文字列が列挙された配列
	*/
	Static Function GetDirectories(path As String, searchPattern As String) As List<String>
		Return GetDirectories(path, searchPattern, SearchOption.TopDirectoryOnly)
	End Function

	/*!
	@brief	ディレクトリ内のディレクトリを列挙する
	@param  中身を調べるディレクトリのパス
	@param  サーチするディレクトリ名のパターン
	@param  サーチする範囲
	@return ディレクトリのパス文字列が列挙された配列
	*/
	Static Function GetDirectories(path As String, searchPattern As String, searchOption As SearchOption) As List<String>
		Dim info = New DirectoryInfo(path)
		Dim infos = info.GetDirectories(searchPattern, searchOption) As List<DirectoryInfo>
		Dim enumerator = infos.GetEnumerator()
		Dim list As List<String>
		While enumerator.MoveNext()
			list.Add(enumerator.Current.ToString)
		Wend
		Return list
	End Function

	/*!
	@brief	ディレクトリのルートディレクトリを取得する
	@param  ディレクトリのパス
	@return ルートディレクトリ
	*/
	Static Function GetDirectoryRoot(path As String) As String
		Return Path.GetPathRoot(path)
	End Function

	/*!
	@brief	ディレクトリ内のファイルを列挙する
	@param  中身を調べるディレクトリのパス
	@return ファイルのパス文字列が列挙された配列
	*/
	Static Function GetFiles(path As String) As List<String>
		Return GetFiles(path, "?*", SearchOption.TopDirectoryOnly)
	End Function

	/*!
	@brief	ディレクトリ内のファイルを列挙する
	@param  中身を調べるディレクトリのパス
	@param  サーチするファイル名のパターン
	@return ファイルのパス文字列が列挙された配列
	*/
	Static Function GetFiles(path As String, searchPattern As String) As List<String>
		Return GetFiles(path, searchPattern, SearchOption.TopDirectoryOnly)
	End Function

	/*!
	@brief	ディレクトリ内のファイルを列挙する
	@param  中身を調べるディレクトリのパス
	@param  サーチするファイル名のパターン
	@param  サーチする範囲
	@return ファイルのパス文字列が列挙された配列
	*/
	Static Function GetFiles(path As String, searchPattern As String, searchOption As SearchOption) As List<String>
		Dim info = New DirectoryInfo(path)
		Dim infos = info.GetFiles(searchPattern, searchOption) As List<FileInfo>
		Dim enumerator = infos.GetEnumerator()
		Dim list As List<String>
		While enumerator.MoveNext()
			list.Add(enumerator.Current.ToString)
		Wend
		Return list
	End Function

	/*!
	@brief	ディレクトリ内を列挙する
	@param  中身を調べるディレクトリのパス
	@return ファイルやディレクトリのパス文字列が列挙された配列
	*/
	Static Function GetFileSystemEntries(path As String) As List<String>
		Return GetFileSystemEntries(path, "?*")
	End Function

	/*!
	@brief	ディレクトリ内を列挙する
	@param  中身を調べるディレクトリのパス
	@param  サーチするファイル名のパターン
	@return ファイルやディレクトリのパス文字列が列挙された配列
	*/
	Static Function GetFileSystemEntries(path As String, searchPattern As String) As List<String>
		Dim info = New DirectoryInfo(path)
		Dim infos = info.GetFileSystemInfos(searchPattern) As List<FileSystemInfo>
		Dim enumerator = infos.GetEnumerator()
		Dim list As List<String>
		While enumerator.MoveNext()
			list.Add(enumerator.Current.ToString)
		Wend
		Return list
	End Function

	/*!
	@brief	ディレクトリの最終アクセス日を取得する
	@param  ディレクトリのパス
	@return 最終アクセス日
	*/
	Static Function GetLastAccessTime(path As String) As DateTime
		Dim info = New DirectoryInfo(path)
		Return info.LastAccessTime
	End Function

	/*!
	@brief	ディレクトリの最終アクセス日をUTC時刻で取得する
	@param  ディレクトリのパス
	@return 最終アクセス日(UTC)
	*/
	Static Function GetLastAccessTimeUtc(path As String) As DateTime
		Dim info = New DirectoryInfo(path)
		Return info.LastAccessTimeUtc
	End Function

	/*!
	@brief	ディレクトリの最終書き込み日を取得する
	@param  ディレクトリのパス
	@return 最終書き込み日
	*/
	Static Function GetLastWriteTime(path As String) As DateTime
		Dim info = New DirectoryInfo(path)
		Return info.LastWriteTime
	End Function

	/*!
	@brief	ディレクトリの最終書き込み日をUTC時刻で取得する
	@param  ディレクトリのパス
	@return 最終書き込み日(UTC)
	*/
	Static Function GetLastWriteTimeUtc(path As String) As DateTime
		Dim info = New DirectoryInfo(path)
		Return info.LastWriteTimeUtc
	End Function

	/*!
	@brief	使用可能な論理ドライブを列挙する
	@return 論理ドライブを列挙したパス文字列
	*/
	Static Function GetLogicalDrives() As List<String>
		Dim drives = WIN32API_GetLogicalDrives() As DWord
		If drives <> 0 Then
			Dim list As List<String>
			Dim i As SByte
			For i = 0 To 25
				If (drives and (1 << i)) <> 0 Then
					list.Add(Chr$(Asc("A") + i) + ":\")
				End If
			Next
			Return list
		Else
			Throw New IOException("Directory.GetLogicalDrives: Failed to GetLogicalDirives.")
		End If
	End Function

	/*!
	@brief	ディレクトリのひとつ上のディレクトリを取得する
	@param  ディレクトリのパス
	@return ひとつ上のディレクトリ
	*/
	Static Function GetParent(path As String) As DirectoryInfo
		Return New DirectoryInfo(Path.GetDirectoryName(path))
	End Function

	/*!
	@brief	ディレクトリを移動する
	@param  移動元のディレクトリのパス
	@param  移動後のディレクトリのパス
	*/
	Static Sub Move(sourceDirName As String, destDirName As String)
		Dim info = New DirectoryInfo(sourceDirName)
		info.MoveTo(destDirName)
	End Sub

	/*
	Static Sub SetAccessControl(path As String, directorySecurity As DirectorySecurity)
	End Sub
	*/

	/*!
	@brief	ディレクトリの作成日を設定する
	@param  ディレクトリのパス
	@param  作成日
	*/
	Static Sub SetCreationTime(path As String, creationTime As DateTime)
		Dim info = New DirectoryInfo(path)
		info.CreationTime = creationTime
	End Sub

	/*!
	@brief	ディレクトリの作成日をUTC時刻で設定する
	@param  ディレクトリのパス
	@param  作成日(UTC)
	*/
	Static Sub SetCreationTimeUtc(path As String, creationTime As DateTime)
		Dim info = New DirectoryInfo(path)
		info.CreationTimeUtc = creationTime
	End Sub

	/*!
	@brief	カレントディレクトリを設定する
	@param  ディレクトリのパス
	*/
	Static Sub SetCurrentDirectory(path As String)
		System.Environment.CurrentDirectory = path
	End Sub

	/*!
	@brief	ディレクトリの最終アクセス日を設定する
	@param  ディレクトリのパス
	@param  最終アクセス日
	*/
	Static Sub SetLastAccessTime(path As String, lastAccessTime As DateTime)
		Dim info = New DirectoryInfo(path)
		info.LastAccessTime = lastAccessTime
	End Sub

	/*!
	@brief	ディレクトリの最終アクセス日をUTC時刻で設定する
	@param  ディレクトリのパス
	@param  最終アクセス日(UTC)
	*/
	Static Sub SetLastAccessTimeUtc(path As String, lastAccessTime As DateTime)
		Dim info = New DirectoryInfo(path)
		info.LastAccessTimeUtc = lastAccessTime
	End Sub

	/*!
	@brief	ディレクトリの最終書き込み日を設定する
	@param  ディレクトリのパス
	@param  最終書き込み日
	*/
	Static Sub SetLastWriteTime(path As String, lastWriteTime As DateTime)
		Dim info = New DirectoryInfo(path)
		info.LastWriteTime = lastWriteTime
	End Sub

	/*!
	@brief	ディレクトリの最終書き込み日をUTC時刻で設定する
	@param  ディレクトリのパス
	@param  最終書き込み日(UTC)
	*/
	Static Sub SetLastWriteTimeUtc(path As String, lastWriteTime As DateTime)
		Dim info = New DirectoryInfo(path)
		info.LastWriteTimeUtc = lastWriteTime
	End Sub
End Class

/* 名前が被ってメソッドから呼び出せない */
Function WIN32API_GetLogicalDrives() As DWord
	Return GetLogicalDrives()
End Function

End Namespace
End Namespace