Imports System.Threading
Imports Smackbio

Public Class MainForm

    Public Delegate Sub delegateAddEvent(msg As String)

    Private m_LogServer As LogServer           'Log Server
    Private m_Running As Boolean               'Is Running Monitor Thread?
    Private m_StopEvent As ManualResetEvent    'Stop Event

    Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        m_Running = False
    End Sub

    Private Sub MainForm_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
        If m_Running Then
            m_Running = False
            m_StopEvent.WaitOne()
        End If
    End Sub

    Private Sub cmdStartMonitoring_Click(sender As Object, e As EventArgs) Handles cmdStartMonitoring.Click
        cmdStartMonitoring.Enabled = False
        cmdStopMonitoring.Enabled = True
        txtPortNo.Enabled = False

        m_Running = True
        m_StopEvent = New ManualResetEvent(False)
        ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf MonitoringThread))
    End Sub

    Private Sub cmdStopMonitoring_Click(sender As Object, e As EventArgs) Handles cmdStopMonitoring.Click
        m_Running = False
        m_StopEvent.WaitOne()

        cmdStartMonitoring.Enabled = True
        cmdStopMonitoring.Enabled = False
        txtPortNo.Enabled = True
    End Sub

    Private Sub cmdClearLogs_Click(sender As Object, e As EventArgs) Handles cmdClearLogs.Click
        lstEvents.Items.Clear()
        lblEventCount.Text = lstEvents.Items.Count.ToString
    End Sub

    Public Sub OnAddEvent(ByVal msg As String)
        lstEvents.Items.Add(msg)
        lblEventCount.Text = lstEvents.Items.Count.ToString
    End Sub

    Public Function OnTimeLog(terminalType As String,
                         terminalID As Integer,
                         serialNumber As String,
                         transactionID As Int32,
                         logTime As DateTime,
                         userID As Int64,
                         doorID As Int32,
                         attendanceStatus As String,
                         verifyMode As String,
                         jobCode As Int32,
                         antipass As String,
                         photo As [Byte]()) As Boolean
        Dim msg As String

        Try
            msg = "[" + terminalType + ":"
            msg += terminalID.ToString
            msg += " SN=" + serialNumber + "] "
            msg += "TimeLog"
            msg += "(" + transactionID.ToString + ") "
            msg += logTime.ToString + ", "
            msg += "UserID=" + String.Format("{0}, ", userID)
            msg += "Door=" + doorID.ToString + ", "
            msg += "AttendStat=" + attendanceStatus + ", "
            msg += "VMode=" + verifyMode + ", "
            msg += "JobCode=" + jobCode.ToString + ", "
            msg += "Antipass=" + antipass + ", "
            If photo Is Nothing Then
                msg += "Photo=No"
            Else
                msg += "Photo=Yes "
                msg += "(" + Convert.ToString(photo.Length) + "bytes)"
            End If

            BeginInvoke(New delegateAddEvent(AddressOf OnAddEvent), msg)
            Return True
        Catch e As Exception
            Return False
        End Try
    End Function

    Public Function OnAdminLog(terminalType As String,
                          terminalID As Int32,
                          serialNumber As String,
                          transactionID As Int32,
                          logTime As DateTime,
                          adminID As Int64,
                          userID As Int64,
                          action As String,
                          result As Int32) As Boolean
        Dim msg As String

        Try
            msg = "[" + terminalType + ":"
            msg += terminalID.ToString
            msg += " SN=" + serialNumber + "] "
            msg += "AdminLog"
            msg += "(" + transactionID.ToString + ") "
            msg += logTime.ToString + ", "
            msg += "AdminID=" + String.Format("{0}, ", adminID)
            msg += "UserID=" + String.Format("{0}, ", userID)
            msg += "Action=" + action + ", "
            msg += "Status=" + String.Format("{0:D}", result)
            BeginInvoke(New delegateAddEvent(AddressOf OnAddEvent), msg)
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

    Public Function OnAlarmLog(terminalType As String,
                          terminalID As Int32,
                          serialNumber As String,
                          transactionID As Int32,
                          logTime As DateTime,
                          userID As Int64,
                          doorID As Int32,
                          alarmType As String) As Boolean
        Dim msg As String

        Try
            msg = "[" + terminalType + ":"
            msg += terminalID.ToString
            msg += " SN=" + serialNumber + "] "
            msg += "AlarmLog"
            msg += "(" + transactionID.ToString() + ") "
            msg += logTime.ToString + ", "
            msg += "UserID=" + String.Format("{0}, ", userID)
            msg += "Door=" + doorID.ToString + ", "
            msg += "Type=" + alarmType
            BeginInvoke(New delegateAddEvent(AddressOf OnAddEvent), msg)
            Return True
        Catch e As Exception
            Return False
        End Try
    End Function

    Public Sub OnPing(terminalType As String,
                      terminalID As Int32,
                      serialNumber As String,
                      transactionID As Int32)
        Dim msg As String

        msg = "[" + terminalType + ":"
        msg += terminalID.ToString
        msg += " SN=" + serialNumber + "] "
        msg += "KeepAlive"
        msg += "(" + transactionID.ToString + ") "
        BeginInvoke(New delegateAddEvent(AddressOf OnAddEvent), msg)
    End Sub

    Private Sub MonitoringThread(state As Object)
        Dim portNum As Int16

        portNum = Convert.ToInt16(txtPortNo.Text)      ' Get port number.
        m_LogServer = New LogServer(portNum, AddressOf OnTimeLog, AddressOf OnAdminLog, AddressOf OnAlarmLog, AddressOf OnPing)   ' Create And start log server.

        ' Watch stop signal.
        While (m_Running)
            Thread.Sleep(100)   ' Simulate some lengthy operations.
        End While

        m_LogServer.Dispose()  ' Dispose log server
        m_StopEvent.Set()      ' Signal the stopped Event.
    End Sub

End Class
