Namespace System
Namespace IO


Class FileSystemInfo
	m_CreationTime As FILETIME
	m_LastAccessTime As FILETIME
	m_LastWriteTime As FILETIME
	m_FileAttributes As FileAttributes

	m_IsFreshed As Boolean
Protected
	FullPath As String
	OriginalPath As String
Public

	/*!
	@brief	コンストラクタ
	@author	OverTaker
	*/
	Sub FileSystemInfo()
		m_IsFreshed = False
	End Sub

	/*!
	@brief	デストラクタ
	@author	OverTaker
	*/
	Sub ~FileSystemInfo()
	End Sub

	/*!
	@brief	値が等しいか比較する
	@author	OverTaker
	@param  比較するオブジェクト
	@return 等しい場合True,そうでない場合False
	*/
	Override Function Equals( object As Object ) As Boolean
		If This.ToString = object.ToString Then
			Return True
		Else
			Return False
		End If
	End Function

	/*!
	@brief	文字列で表したオブジェクトを取得する
	@author	OverTaker
	@return オブジェクトの文字列(ファイルパス)
	*/
	Override Function ToString() As String
		Return FullPath
	End Function

	'----------------------------------------------------------------
	' パブリック プロパティ
	'----------------------------------------------------------------

	/*!
	@brief	ファイルの属性を取得する
	@author	OverTaker
	@return ファイル属性
	*/
	Function Attributes() As FileAttributes
		If Not m_IsFreshed Then Refresh()
		Return m_FileAttributes
	End Function

	/*!
	@brief	ファイル属性を設定する
	@author	OverTaker
	@param  ファイル属性
	*/
	Sub Attributes(value As FileAttributes)
		If Not SetFileAttributes(ToTCStr(FullPath), value) Then
			Throw New IOException("FileSystemInfo.Attributes: Failed to SetFileAttributes.")
		End If
	End Sub

	/*!
	@brief	ファイル作成日を取得する
	@author	OverTaker
	@return ファイルの作成日
	*/
	Function CreationTime() As DateTime
		If Not m_IsFreshed Then Refresh()
		Return DateTime.FromFileTime(m_CreationTime)
	End Function

	/*!
	@brief	ファイル作成日を設定する
	@author	OverTaker
	@param  ファイルの作成日
	*/
	Sub CreationTime(ByRef value As DateTime)
		m_CreationTime = value.ToFileTimeUtc()
		setFileTime()
	End Sub

	/*!
	@brief	ファイル作成日をUTC時刻で取得する
	@author	OverTaker
	@return ファイルの作成日(UTC)
	*/
	Function CreationTimeUtc() As DateTime
		Return CreationTime.ToUniversalTime()
	End Function

	/*!
	@brief	ファイル作成日をUTC時刻で設定する
	@author	OverTaker
	@param  ファイルの作成日(UTC)
	*/
	Sub CreationTimeUtc(ByRef value As DateTime)
		CreationTime = value
	End Sub

	/*!
	@brief	ファイル最終アクセス日を取得する
	@author	OverTaker
	@return ファイルの最終アクセス日
	*/
	Function LastAccessTime() As DateTime
		If Not m_IsFreshed Then Refresh()
		Return DateTime.FromFileTime(m_LastAccessTime)
	End Function

	/*!
	@brief	ファイル最終アクセス日を設定する
	@author	OverTaker
	@param  ファイルの最終アクセス日
	*/
	Sub LastAccessTime(ByRef value As DateTime)
		m_LastAccessTime = value.ToFileTimeUtc()
		setFileTime()
	End Sub

	/*!
	@brief	ファイル最終アクセス日をUTC時刻で取得する
	@author	OverTaker
	@return ファイルの最終アクセス日(UTC)
	*/
	Function LastAccessTimeUtc() As DateTime
		Return LastAccessTime.ToUniversalTime()
	End Function

	/*!
	@brief	ファイル最終アクセス日をUTC時刻で設定する
	@author	OverTaker
	@param  ファイルの最終アクセス日(UTC)
	*/
	Sub LastAccessTimeUtc(ByRef value As DateTime)
		LastAccessTime = value
	End Sub

	/*!
	@brief	ファイルの最終書き込み日を取得する
	@author	OverTaker
	@return ファイルの最終書き込み日
	*/
	Function LastWriteTime() As DateTime
		If Not m_IsFreshed Then Refresh()
		Return DateTime.FromFileTime(m_LastWriteTime)
	End Function

	/*!
	@brief	ファイルの最終書き込み日を設定する
	@author	OverTaker
	@param  ファイルの最終書き込み日
	*/
	Sub LastWriteTime(ByRef value As DateTime)
		m_LastWriteTime = value.ToFileTimeUtc()
		setFileTime()
	End Sub

	/*!
	@brief	ファイルの最終書き込み日をUTC時刻で取得する
	@author	OverTaker
	@return ファイルの最終書き込み日(UTC)
	*/
	Function LastWriteTimeUtc() As DateTime
		Return LastWriteTime.ToUniversalTime()
	End Function

	/*!
	@brief	ファイルの最終書き込み日をUTC時刻で設定する
	@author	OverTaker
	@param  ファイルの最終書き込み日(UTC)
	*/
	Sub LastWriteTimeUtc(ByRef value As DateTime)
		LastWriteTime = value
	End Sub

	/*!
	@brief	ファイルが存在するかどうかを取得する
	@author	OverTaker
	@return ファイルが存在する場合True,そうでない場合False
	*/
	Function Exists() As Boolean
		Return File.Exists(FullPath)
	End Function

	/*!
	@brief	ファイル拡張子を取得する
	@author	OverTaker
	@return ファイル拡張子
	*/
	Function Extension() As String
		Return Path.GetExtension(FullPath)
	End Function

	/*!
	@brief	ファイルパスを取得する
	@author	OverTaker
	@return ファイルパス
	*/
	Function FullName() As String
		Return FullPath
	End Function

	/*!
	@brief	ファイル名を取得する
	@author	OverTaker
	@return ファイル名
	*/
	Function Name() As String
		Return Path.GetFileName(FullPath)
	End Function


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

	/*!
	@brief	ファイルを削除する
	@author	OverTaker
	*/
	Virtual Sub Delete()
		If DeleteFile(ToTCStr(FullPath)) = FALSE Then
			Throw New IOException("FileSystemInfo.Delete: Failed to DeleteFile.")
		End If
	End Sub

	/*!
	@brief  ファイルを最新の情報に更新する
	@author	OverTaker
	*/
	Virtual Sub Refresh()
		Dim data As WIN32_FIND_DATA
		Dim hFind = FindFirstFile(ToTCStr(FullPath), data)
		FindClose(hFind)

		If hFind <> INVALID_HANDLE_VALUE Then
			m_FileAttributes = New FileAttributes(data.dwFileAttributes As Long, "FileAttributes")
			m_CreationTime = data.ftCreationTime
			m_LastAccessTime = data.ftLastAccessTime
			m_LastWriteTime = data.ftLastWriteTime
			m_IsFreshed = True
		Else
			Throw New IOException("FileSystemInfo.Refresh: Failed to FindFirstFile.")
		End If
	End Sub

	
	'----------------------------------------------------------------
	' パブリック プライベート
	'----------------------------------------------------------------
Private

	/*!
	@brief  ファイルの時間を更新する
	@author	OverTaker
	*/
	Sub setFileTime()
		If Not m_IsFreshed Then Refresh()
		Dim hFile = CreateFile(ToTCStr(FullPath), GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, ByVal 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
		If hFile = INVALID_HANDLE_VALUE Then
			Throw New IOException("FileSystemInfo.setFileTime: Failed to CreateFile.")
			Exit Function
		End If

		If SetFileTime(hFile, m_CreationTime, m_LastAccessTime, m_LastWriteTime) = False Then
			CloseHandle(hFile)
			Throw New IOException("FileSystemInfo.setFileTime: Failed to SetFileTime.")
		End If

		CloseHandle(hFile)
	End Sub
End Class


End Namespace
End Namespace
