Imports System.Threading

Public Class RuningLog

    Enum LogType
        e_none
        e_info
        e_Error
        e_warning

    End Enum
    Enum LogMode
        ''' <summary>
        ''' 文本
        ''' </summary>
        e_file
        ''' <summary>
        ''' 控制台
        ''' </summary>
        e_console
        ''' <summary>
        ''' 文本框
        ''' </summary>
        e_RichTextBox
        ''' <summary>
        ''' 文件和控制台
        ''' </summary>
        e_fileandconsole
        ''' <summary>
        ''' 文件和文本框
        ''' </summary>
        e_fileandRichTextBox
        ''' <summary>
        ''' 控制台和文本框
        ''' </summary>
        e_consoleandRichTextBox
        ''' <summary>
        ''' 文件、控制台和文本框
        ''' </summary>
        e_both

    End Enum
    ''' <summary>
    ''' 日志显示等级
    ''' </summary>
    Public LogLevel As Integer = 0
    ''' <summary>
    ''' 日志队列
    ''' </summary>
    Public logQueue As New Queue(Of LogNode)
    '日志输出文本框
    Public RichTextBox As RichTextBox
    '日志输出文件夹路径
    Public LogFilePath As String
    '日志输出线程
    Public LogThread As Thread
    Sub New(ric As RichTextBox, logFile As String)
        LogFilePath = logFile
        RichTextBox = ric
        logQueue = New Queue(Of LogNode)
        LogThread = New Thread(AddressOf LogThreadFunc)
        LogThread.Start()
    End Sub


    Public Sub LogThreadFunc()
        Dim str As LogNode
        While True
            If logQueue.Count > 0 Then
                str = logQueue.Dequeue

                '判断输出模式
                Select Case str.LogMode
                    Case LogMode.e_file
                        WriteLog(str)
                    Case LogMode.e_console
                        Console.WriteLine(str.LogText)
                    Case LogMode.e_RichTextBox
                        WriteRichTextBox(str)
                    Case LogMode.e_fileandconsole
                        WriteLog(str)
                        Console.WriteLine(str.LogText)
                    Case LogMode.e_fileandRichTextBox
                        WriteLog(str)
                        WriteRichTextBox(str)
                    Case LogMode.e_consoleandRichTextBox
                        Console.WriteLine(str.LogText)
                        WriteRichTextBox(str)
                    Case LogMode.e_both
                        WriteLog(str)
                        Console.WriteLine(str.LogText)
                        WriteRichTextBox(str)
                End Select



            End If
            Thread.Sleep(10)
        End While
    End Sub

    '添加日志节点
    Public Sub AddLogNode(node As LogNode）
        logQueue.Enqueue(node)
    End Sub

    '关闭线程
    Public Sub CloseThread()
        '判断线程初始化 和是否在运行
        If Not IsNothing(LogThread) And LogThread.IsAlive Then
            LogThread.Abort()
        End If

    End Sub

    '写入文本框
    Delegate Sub dWriteRichTextBox(node As LogNode)
    Public Sub WriteRichTextBox(node As LogNode)
        If IsNothing(RichTextBox) Then Return
        If RichTextBox.InvokeRequired Then
            RichTextBox.Invoke(New dWriteRichTextBox(AddressOf WriteRichTextBox), node)

        Else
            If LogLevel <= node.LogType Then
                '设置文本 字体和文本颜色即字号大小并在输入框末尾追加文本并设置
                Dim SelectionStart As Integer = RichTextBox.Text.Length
                '写入日志
                Dim logtxt As String = node.LogText & vbCrLf
                '判断是否要加消息类型
                If node.ShowType Then
                    logtxt = RuningLog.AddLogType(logtxt, node.LogType)
                End If
                '判断是否要加时间戳
                If node.ShowTime Then
                    logtxt = RuningLog.AddTimeStamps(logtxt)
                End If
                RichTextBox.AppendText(logtxt)
                '并设置颜色、字号、字体、
                RichTextBox.Select(SelectionStart, logtxt.Length)
                RichTextBox.SelectionColor = node.LogColor
                RichTextBox.SelectionFont = node.LogFont
                '设置字体大小
                RichTextBox.SelectionLength = 0

                'RichTextBox.SelectionFont = node.LogFont
                'RichTextBox.SelectionColor = node.LogColor
                '
                'RichTextBox.SelectionLength = 0
                'RichTextBox.SelectedText = node.LogText

            End If

        End If

    End Sub


    '写入日志
    Public Sub WriteLog(node As LogNode)
        '判断文件夹是否存在，不存在则创建 创建失败则退出
        If Not System.IO.Directory.Exists(LogFilePath) Then
            System.IO.Directory.CreateDirectory(LogFilePath)
        End If
        '以日期为文件名
        Dim fileName As String = Now.ToString("yyyy-MM-dd") & ".log"
        '判断文件是否存在，不存在则创建,创建失败则退出
        If Not System.IO.File.Exists(LogFilePath & "\" & fileName) Then
            Try
                System.IO.File.Create(LogFilePath & "\" & fileName).Dispose()
            Catch ex As Exception
                Return
            End Try
        End If
        '写入日志
        Dim logtxt As String = node.LogText
        '判断是否要加消息类型
        If node.ShowType Then
            logtxt = RuningLog.AddLogType(logtxt, node.LogType)
        End If
        '判断是否要加时间戳
        If node.ShowTime Then
            logtxt = RuningLog.AddTimeStamps(logtxt)
        End If

        System.IO.File.AppendAllText(LogFilePath & "\" & fileName, logtxt & vbCrLf)


    End Sub


    '字符串附加时间戳
    Public Shared Function AddTimeStamps(str As String) As String
        Return Now.ToString("yyyy-MM-dd HH:mm:ss:fff") & " " & str
    End Function
    '字符串加消息类型
    Public Shared Function AddLogType(str As String, logType As LogType) As String
        Select Case logType
            Case LogType.e_info
                Return "[Info] " & str
            Case LogType.e_Error
                Return "[Error] " & str
            Case LogType.e_warning
                Return "[Warning] " & str
            Case Else
                Return str
        End Select

    End Function


End Class
'日志文件节点类
Public Class LogNode
    Public LogType As RuningLog.LogType
    Public LogText As String
    'Public InputText As String
    Public LogTime As DateTime
    Public LogMode As RuningLog.LogMode
    '文本颜色
    Public LogColor As Color
    '文本字体  '文本字号
    Public LogFont As Font


    '是否显示时间
    Public ShowTime As Boolean = True
    '是否显示类型
    Public ShowType As Boolean = True

    Sub New(logtxt As String, nLogType As Integer, nLogMode As Integer)
        LogText = logtxt
        LogType = nLogType
        LogMode = nLogMode
        'InputText = LogText
        '默认字体为宋体 字号为 18 颜色为黑色
        LogFont = New Font("宋体", 9)
        LogColor = Color.Black
        '显示时间和类型
        ShowTime = True

        ShowType = True


    End Sub

    '设置文本颜色
    Public Sub SetLogColor(color As Color)
        LogColor = color
    End Sub
    '设置文本字体
    Public Sub SetLogFont(font As Font)
        LogFont = font
    End Sub

    '设置是否显示时间
    Public Sub SetShowTime(showTime As Boolean)
        showTime = showTime
        ' InputText = RuningLog.AddTimeStamps(LogText)
    End Sub

    '设置是否显示类型
    Public Sub SetShowType(showType As Boolean)
        showType = showType
        'InputText = RuningLog.AddLogType(LogText, LogType)
    End Sub
End Class