Imports OfficeImageReducer.ClassMyCommon ''ClassMyCoomonのプロパティ・メソッドを参照するためのImportsステートメント

''' <summary>ログ管理クラス</summary>
Public Class ClassLog

    ''' <summary>フルパスでのログファイル名</summary>
    Private LogFileName As String

    ''' <summary>ログファイル保存用の裏バッファ</summary>
    Private _ShadowBuf As String

    ''' <summary>フォーム上のログ表示用テキストボックス</summary>
    Private _LogTextBox As TextBox

    ''' <summary>コンストラクタ</summary>
    ''' <param name="LogTextBox">フォーム上のログ表示用テキストボックス</param>
    Public Sub New(LogTextBox As TextBox)
        _LogTextBox = LogTextBox
        _LogTextBox.Text = ""
        _ShadowBuf = ""
        LogFileName = AppPath() + TITLE + "Log" + Now.ToString("yyMMdd") + ".txt"
    End Sub

    ''' <summary>Delegate ログの追加</summary>
    ''' <param name="stradd">ログ追加文字列</param>
    Delegate Sub Add_Callback(ByVal stradd As String)

    ''' <summary>ログの追加</summary>
    ''' <param name="stradd">ログ追加文字列</param>
    ''' <remarks>ログの最下行へのスクロール・表示更新は行わない</remarks>
    Public Sub Add(ByVal stradd As String)

        ''別スレッドか判定
        If _LogTextBox.InvokeRequired Then
            ''別スレッドからの場合コールバック処理をして終了
            Dim d As New Add_Callback(AddressOf Add)
            _LogTextBox.Invoke(d, New Object() {stradd})
            Exit Sub
        End If

        If Len(stradd) = 0 Then Exit Sub

        'ログに追加する文字列の先頭にタイムスタンプを追加する
        Dim TimeStamp As String = Format(Now, "MM/dd HH:mm:ss") & " : "
        stradd = TimeStamp & stradd

        '末尾のvbCrLfをいったん削除
        If Strings.Right(stradd, vbCrLf.Length) = vbCrLf Then
            stradd = Strings.Left(stradd, stradd.Length - vbCrLf.Length)
        End If

        '中間にある vbCrLf を vbCrLf + タイムスタンプに置換
        stradd = stradd.Replace(vbCrLf, vbCrLf & TimeStamp)

        '末尾にvbCrLfを追加
        stradd = stradd & vbCrLf

        _LogTextBox.Text &= stradd
        _ShadowBuf &= stradd

    End Sub

    ''' <summary>Delegate ログの追加と表示の更新</summary>
    ''' <param name="stradd">ログ追加文字列</param>
    Delegate Sub Put_Callback(ByVal stradd As String)

    ''' <summary>ログの追加と最下行へのスクロール・表示更新</summary>
    ''' <param name="stradd">ログ追加文字列</param>
    Public Sub Put(ByVal stradd As String)

        ''別スレッドか判定
        If _LogTextBox.InvokeRequired Then
            ''別スレッドからの場合コールバック処理をして終了
            Dim d As New Put_Callback(AddressOf Put)
            _LogTextBox.Invoke(d, New Object() {stradd})
            Exit Sub
        End If

        ''古いログの表示を削除する
        DeleteOld()

        ''ログ追加処理
        Add(stradd)

        ''カレット位置を末尾に移動
        _LogTextBox.SelectionStart = _LogTextBox.Text.Length
        ''カレット位置までスクロール
        _LogTextBox.ScrollToCaret()

    End Sub

    ''' <summary>デバッグログの追加と最下行へのスクロール・表示更新</summary>
    ''' <param name="stradd">デバッグログ追加文字列</param>
    Public Sub DebugPut(ByVal stradd As String)

#If 0 Then
            Put(stradd)
#End If

    End Sub

    ''' <summary>ログをファイルへ保存する</summary>
    Public Sub Save()

        If _ShadowBuf.Length = 0 Then Exit Sub
#If 0 Then 'このプログラムでは保存機能は封印する。
        ''追記モードでShift-JISファイルを開く
        Using Writer As New System.IO.StreamWriter(LogFileName, True, System.Text.Encoding.GetEncoding("shift-jis"))
            Writer.Write(_ShadowBuf)
        End Using
#End If
        _ShadowBuf = ""

    End Sub

    ''' <summary>古いログの表示を削除する</summary>
    Private Sub DeleteOld()
        Dim SplitBuf() As String

        ''ログ表示量が MaxLength -1024 より小さくなるまで破棄する。
        While Len(_LogTextBox.Text) > (_LogTextBox.MaxLength - 1024)
            SplitBuf = Split(_LogTextBox.Text, vbLf, 2)
            If UBound(SplitBuf) > 0 Then
                _LogTextBox.Text = SplitBuf(1)
            Else
                _LogTextBox.Text = ""
            End If
        End While
    End Sub

    ''' <summary>ログ表示を消去する。</summary>
    ''' <remarks >ファイル保存用の裏バッファはクリアしない</remarks>
    Public Sub Clear()
        _LogTextBox.Text = ""
    End Sub

End Class
