Namespace System
	Namespace Diagnostics

		' リスナ
		Class TraceListener
			indentLevel As Long
			indentSize As Long

		Protected
			Function GetIndentString() As String
				Dim i As Long

				Dim IndentStr = ""
				For i = 0 To ELM( indentSize )
					IndentStr = IndentStr + " "
				Next

				Dim ResultStr = ""
				For i = 0 To ELM( indentLevel )
					ResultStr = ResultStr + IndentStr
				Next

				Return ResultStr
			End Function

		Public
			Sub TraceListener()
				indentLevel = 0
				indentSize = 4
			End Sub

			' コピーコンストラクタ
			Sub TraceListener( ByRef listener As TraceListener )
				indentLevel = listener.indentLevel
				indentSize = listener.indentSize
			End Sub


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

			Virtual Sub Write( message As String )
				'派生クラスで実装 (基底では何もしない）
			End Sub
			Virtual Sub Write( value As Object )
				Write( value.ToString() )
			End Sub
			Virtual Sub Write( value As Object, category As String )
				Write( category + ": " + value.ToString() )
			End Sub
			Virtual Sub Write( message As String, category As String )
				Write( category + ": " + message )
			End Sub

			Virtual Sub WriteLine( message As String )
				'派生クラスで実装 (基底では何もしない）
			End Sub
			Virtual Sub WriteLine( value As Object )
				WriteLine( value.ToString() )
			End Sub
			Virtual Sub WriteLine( value As Object, category As String )
				WriteLine( category + ": " + value.ToString() )
			End Sub
			Virtual Sub WriteLine( message As String, category As String )
				WriteLine( category + ": " + message )
			End Sub

			' 条件をもとに文字列を出力
			Sub WriteIf( condition As Boolean, value As Object )
				If condition Then
					Write( value )
				End If
			End Sub
			Sub WriteIf( condition As Boolean, message As String )
				If condition Then
					Write( message )
				End If
			End Sub
			Sub WriteIf( condition As Boolean, value As Object, category As String )
				If condition Then
					Write( value, category )
				End If
			End Sub
			Sub WriteIf( condition As Boolean, message As String, category As String )
				If condition Then
					Write( message, category )
				End If
			End Sub

			' 条件をもとに文字列を出力
			Sub WriteLineIf( condition As Boolean, value As Object )
				If condition Then
					WriteLine( value )
				End If
			End Sub
			Sub WriteLineIf( condition As Boolean, message As String )
				If condition Then
					WriteLine( message )
				End If
			End Sub
			Sub WriteLineIf( condition As Boolean, value As Object, category As String )
				If condition Then
					WriteLine( value, category )
				End If
			End Sub
			Sub WriteLineIf( condition As Boolean, message As String, category As String )
				If condition Then
					WriteLine( message, category )
				End If
			End Sub


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

			' IndentLevelプロパティ
			Function IndentLevel() As Long
				Return indentLevel
			End Function
			Sub IndentLevel( indentLevel As Long )
				This.indentLevel = indentLevel
			End Sub

			' IndentSizeプロパティ
			Function IndentSize() As Long
				Return indentSize
			End Function
			Sub IndentSize( size As Long )
				indentSize = size
			End Sub
		End Class

		' デフォルトリスナ（デバッガビューへの出力）
		Class DefaultTraceListener
			Inherits TraceListener
		Public

			Override Sub Write( message As String )
				' デバッグビューへ出力
				Dim tempStr = GetIndentString() + message
				OutputDebugString( ToTCStr(tempStr) )

				' デバッグログへ書き込む
				' TODO: 実装
			End Sub

			Override Sub WriteLine( message As String )
				Write( GetIndentString() + message + Ex"\r\n" )
			End Sub
		End Class

	End Namespace
End Namespace
