Imports System.Collections.Generic

Namespace System
Namespace IO

Class DirectoryInfo
	Inherits FileSystemInfo
Public
	Sub DirectoryInfo(path As String)
		OriginalPath = path
		FullPath = Path.GetFullPath(path)
	End Sub

	Sub ~DirectoryInfo()
	End Sub

	'Public Property
	Function Parent() As DirectoryInfo
		Return New DirectoryInfo(Path.GetDirectoryName(FullPath))
	End Function

	Function Root() As DirectoryInfo
		Return New DirectoryInfo(Path.GetPathRoot(FullPath))
	End Function

	'Public Method
	Sub Create()
		CreateDirectory(ToTCStr(FullPath), NULL)
	End Sub

/*	Sub Create(directorySecurity As DirectorySecurity)
	End Sub*/

	Override Sub Delete()
		RemoveDirectory(ToTCStr(FullPath))
	End Sub

	Sub Delete(recursive As Boolean)
		If recursive Then
			' ディレクトリ内のすべての情報を削除する

			Dim dirPath = FullPath As String

			' 終端の '\' を除去
			If dirPath[dirPath.Length-1] = Asc("\") Then
				dirPath = dirPath.Substring(0, dirPath.Length-1)
			End If

			' double null-terminated にする
			dirPath = dirPath + Chr$(0)

			Dim op As SHFILEOPSTRUCT
			op.hwnd = NULL
			op.wFunc = FO_DELETE
			op.pFrom = ToTCStr(dirPath)
			op.pTo = NULL
			op.fFlags = FOF_NOCONFIRMATION or FOF_NOERRORUI or FOF_SILENT

			If SHFileOperation(op) <> 0 Then
				' TODO: エラー処理
				debug
			End If
		Else
			' ディレクトリが空の場合は削除する
			This.Delete()
		End If
	End Sub

/*	Function GetAccessControl() As DirectorySecurity
	End Function*/

/*	Function GetAccessControl(includeSections As AccessControlSections) As DirectorySecurity
	End Function*/

	Function GetDirectories() As List<DirectoryInfo>
		Return GetDirectories("?*")
	End Function

	Function GetDirectories(searchPattern As String) As List<DirectoryInfo>
		Dim infos As List<FileSystemInfo>
		infos = GetFileSystemInfos(searchPattern)

		Dim dirs As List<DirectoryInfo>
		Dim i As Long
		For i = 0 To ELM(infos.Count)
			If infos[i].GetType.ToString() = "DirectoryInfo" Then
				dirs.Add(infos[i] As DirectoryInfo)
			End If
		Next
		Return dirs
	End Function

	Function GetDirectories(searchPattern As String, searchOption As SearchOption) As List<DirectoryInfo>
		Select Case searchOption
			Case SearchOption.TopDirectoryOnly
				Return GetDirectories(searchPattern)
			Case SearchOption.AllDirectories
				Dim dirs As List<DirectoryInfo>
				dirs = GetDirectories(searchPattern)

				Dim subdirs As List<DirectoryInfo>
				Dim i As Long, j As Long
				For i = 0 To ELM(dirs.Count)
					subdirs = dirs[i].GetDirectories(searchPattern)
					For j = 0 To ELM(subdirs.Count)
						dirs.Add(subdirs[j])
					Next
				Next
				Return dirs
		End Select
	End Function

	Function GetFiles() As List<FileInfo>
		Return GetFiles("?*")
	End Function

	Function GetFiles(searchPattern As String) As List<FileInfo>
		Dim infos As List<FileSystemInfo>
		infos = GetFileSystemInfos(searchPattern)

		Dim files As List<FileInfo>
		Dim i As Long
		For i = 0 To ELM(infos.Count)
			If infos[i].GetType.ToString() = "FileInfo" Then
				files.Add(infos[i] As FileInfo)
			End If
		Next
		Return files
	End Function

	Function GetFiles(searchPattern As String, searchOption As SearchOption) As List<FileInfo>
		Select Case searchOption
			Case SearchOption.TopDirectoryOnly
				Return GetFiles(searchPattern)
			Case SearchOption.AllDirectories
				Dim dirs As List<DirectoryInfo>
				dirs = GetDirectories("?*", SearchOption.AllDirectories)

				Dim files As List<FileInfo>
				files = GetFiles(searchPattern)
				Dim i As Long, j As Long, subfiles As List<FileInfo>
				For i = 0 To ELM(dirs.Count)
					subfiles = dirs[i].GetFiles(searchPattern)
					For j = 0 To ELM(subfiles.Count)
						files.Add(subfiles[j])
					Next
				Next
				Return files
		End Select
	End Function

	Function GetFileSystemInfos() As List<FileSystemInfo>
		Return GetFileSystemInfos("?*")
	End Function

	Function GetFileSystemInfos(searchPattern As String) As List<FileSystemInfo>
		Dim find As HANDLE
		Dim findData As WIN32_FIND_DATA
		find = FindFirstFile(ToTCStr(Path.Combine(FullPath, searchPattern)), findData)
		If find = INVALID_HANDLE_VALUE Then
			Return New List<DirectoryInfo>
		End If

		Dim files As List<FileSystemInfo>
		Do
			Dim s = New String(findData.cFileName As PCTSTR)
			If (findData.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY) = FILE_ATTRIBUTE_DIRECTORY Then
				files.Add(New DirectoryInfo(Path.Combine(FullPath, s)))
			Else
				files.Add(New FileInfo(Path.Combine(FullPath, s)))
			End If
		Loop While FindNextFile(find, findData)
		FindClose(find)

		files.Remove(New DirectoryInfo(Path.Combine(FullPath, ".")))
		files.Remove(New DirectoryInfo(Path.Combine(FullPath, "..")))

		If GetLastError() = ERROR_NO_MORE_FILES Then
			Return files
		Else
			debug 'Exception
			Return Nothing
		End If
	End Function

	Sub MoveTo(destDirName As String)
		If MoveFile(ToTCStr(FullPath), ToTCStr(destDirName)) = FALSE Then
			'Exception
		End If
	End Sub

/*	Sub SetAccessControl(directorySecurity As DirectorySecurity)
	End Sub*/

End Class

End Namespace
End Namespace
