Option Strict On

Imports System.IO
Imports System.Drawing
Imports System.Delegate
Imports System.Text
Imports System.Threading
Imports System.Runtime.Serialization.Formatters.Binary

Imports Mbark.Threading
Imports Mbark.UI
Imports Mbark.SensorMessages

Imports CM_VERIFIERSCANNERLib

Namespace Mbark.Sensors
    Public Class CrossMatchVerifier300
        Inherits BaseSensor

#Region " Windows Form Designer generated code "

        Public Sub New()
            MyBase.New()

            'This call is required by the Windows Form Designer.
            InitializeComponent()

            'Add any initialization after the InitializeComponent() call

        End Sub

        'UserControl overrides dispose to clean up the component list.
        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
            If disposing Then
                If Not (components Is Nothing) Then
                    components.Dispose()
                End If
            End If
            MyBase.Dispose(disposing)
        End Sub

        'Required by the Windows Form Designer
        Private components As System.ComponentModel.IContainer

        'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form Designer.  
        'Do not modify it using the code editor.
        Friend WithEvents mCrossMatchSingleLive As System.Windows.Forms.PictureBox
        Friend WithEvents mCrossMatchVerifyCtrl As AxCM_VERIFIERFINGERPRINTLib.AxVerifierFingerprint
        <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
            Dim resources As System.Resources.ResourceManager = New System.Resources.ResourceManager(GetType(CrossMatchVerifier300))
            Me.mCrossMatchSingleLive = New System.Windows.Forms.PictureBox
            Me.mCrossMatchVerifyCtrl = New AxCM_VERIFIERFINGERPRINTLib.AxVerifierFingerprint
            Me.InnerPanel.SuspendLayout()
            Me.MainPanel.SuspendLayout()
            CType(Me.OuterPanel, System.ComponentModel.ISupportInitialize).BeginInit()
            Me.OuterPanel.SuspendLayout()
            CType(Me.mCrossMatchVerifyCtrl, System.ComponentModel.ISupportInitialize).BeginInit()
            Me.SuspendLayout()
            '
            'TimeoutIndicator
            '
            Me.TimeoutIndicator.Name = "TimeoutIndicator"
            '
            'CancelSensorButton
            '
            Me.CancelSensorButton.Name = "CancelSensorButton"
            '
            'ActivateSensorButton
            '
            Me.ActivateSensorButton.Name = "ActivateSensorButton"
            '
            'InnerPanel
            '
            Me.InnerPanel.Name = "InnerPanel"
            '
            'MainPanel
            '
            Me.MainPanel.Controls.Add(Me.mCrossMatchVerifyCtrl)
            Me.MainPanel.Controls.Add(Me.mCrossMatchSingleLive)
            Me.MainPanel.Name = "MainPanel"
            '
            'OuterPanel
            '
            Me.OuterPanel.Name = "OuterPanel"
            '
            'mCrossMatchSingleLive
            '
            Me.mCrossMatchSingleLive.BackColor = System.Drawing.SystemColors.ActiveBorder
            Me.mCrossMatchSingleLive.Dock = System.Windows.Forms.DockStyle.Fill
            Me.mCrossMatchSingleLive.Location = New System.Drawing.Point(0, 0)
            Me.mCrossMatchSingleLive.Name = "mCrossMatchSingleLive"
            Me.mCrossMatchSingleLive.Size = New System.Drawing.Size(280, 152)
            Me.mCrossMatchSingleLive.TabIndex = 0
            Me.mCrossMatchSingleLive.TabStop = False
            Me.mCrossMatchSingleLive.Visible = False
            '
            'mCrossMatchVerifyCtrl
            '
            Me.mCrossMatchVerifyCtrl.ContainingControl = Me
            Me.mCrossMatchVerifyCtrl.Dock = System.Windows.Forms.DockStyle.Fill
            Me.mCrossMatchVerifyCtrl.Enabled = True
            Me.mCrossMatchVerifyCtrl.Location = New System.Drawing.Point(0, 0)
            Me.mCrossMatchVerifyCtrl.Name = "mCrossMatchVerifyCtrl"
            Me.mCrossMatchVerifyCtrl.OcxState = CType(resources.GetObject("mCrossMatchVerifyCtrl.OcxState"), System.Windows.Forms.AxHost.State)
            Me.mCrossMatchVerifyCtrl.Size = New System.Drawing.Size(280, 152)
            Me.mCrossMatchVerifyCtrl.TabIndex = 1
            '
            'CrossMatchVerifier300
            '
            Me.Name = "CrossMatchVerifier300"
            Me.InnerPanel.ResumeLayout(False)
            Me.MainPanel.ResumeLayout(False)
            CType(Me.OuterPanel, System.ComponentModel.ISupportInitialize).EndInit()
            Me.OuterPanel.ResumeLayout(False)
            CType(Me.mCrossMatchVerifyCtrl, System.ComponentModel.ISupportInitialize).EndInit()
            Me.ResumeLayout(False)

        End Sub

#End Region

        Private Sub CreateNew()
            WritableRequiresConfiguration = False
            WritableHasConfigurationClass = False
            'if Configuration Class exist, must set mConfigurationClassname
        End Sub
        Private Const CrossMatchV300CriticalTime As Integer = 3000

        Private Const CaptureCommandExpirationTime As Integer = 12000 'ms 
        Private Const InitializationExpirationTime As Integer = 30000 'ms
        Private Const DownloadCommandExpirationTime As Integer = 5000 'ms
        Private Const ConfigurationCommandExpirationTime As Integer = 10000 'ms

        Private mLogFolderLocation As String
        Private mLogFileName As String
        'Private Const ID500AspectRatio As Single = 1808.0! / 1024.0!

        Private mActive As Boolean = False
        Private mAutoMode As Boolean = False 'this mode can be set by the user from the interface in the future

        Protected Delegate Function ProcessDelegate() As Object
        Protected Delegate Function CaptureDelegate(ByVal CmdGuid As Guid) As Object
        Private mModality As SensorModality = SensorModality.Fingerprint
        Public Overrides ReadOnly Property Modality() As SensorModality
            Get
                Return mModality
            End Get
        End Property
        Public Overrides ReadOnly Property IsActive() As Boolean
            Get
                Return mActive
            End Get
        End Property

        Private mName As String = "Cross Match"
        Public Overrides ReadOnly Property FriendlyName() As String
            Get
                Return mName
            End Get
        End Property

#Region "       Initialization      "
        Public Overrides ReadOnly Property InitializationCommandTemplate() As Threading.AsyncCommandTemplate
            Get
                Static init As AsyncCommandTemplate
                If init Is Nothing Then
                    init = New AsyncCommandTemplate
                    With init
                        .TargetMethod = CreateDelegate(GetType(ProcessDelegate), Me, "Initialization")
                        .ExpirationTime = InitializationExpirationTime
                        .IgnoreUnderlyingHandleOfTargetControl = True
                    End With
                End If
                Return init
            End Get
        End Property

        Private mIsInitialized As Boolean = False
        Private Function Initialization() As Object
            Try
                'If mCrossMatchVerifyCtrl.IsInitialized = 0 Then
                mCrossMatchVerifyCtrl.Initialize(mLogFolderLocation, mLogFileName)
                'System.Threading.Thread.Sleep(3000)

                SensorProperties()
                MarkAsOnline()
                'End If

            Catch ex As ThreadInterruptedException
                MarkAsOffline()
                WritableRequiresRecovery = True
                Dim ite As New InitializationTimeoutException
                ite.Sensor = Me
                ite.MachineNotes = SensorMessages.Messages.InitializationTimedOut
                Throw ite
            Catch ex As Exception
                MarkAsOffline()
                WritableRequiresRecovery = True
                Dim ife As InitializationFailureException
                ife.Sensor = Me
                ife.MachineNotes = SensorMessages.Messages.InitializationFailed
                Throw ife
            End Try
        End Function
        Private mSensorProperties As New SensorProperties
        Private Sub SensorProperties()
            With mCrossMatchVerifyCtrl
                mSensorProperties.Manufacturer = "Cross Match"
                mSensorProperties.ModelName = .OfficialScannerName
                mName = "Cross Match " & .OfficialScannerName
                mSensorProperties.SerialNumber = .ScannerSerialNo
                mSensorProperties.VendorLibraryName = .ModuleName
                mSensorProperties.VendorLibraryVersion = .ModuleVersion
                mSensorProperties.Modality = Modality
            End With
        End Sub
#End Region

#Region "       Configuration         "

        Private mIsConfigured As Boolean = False
        Public Overrides ReadOnly Property ConfigurationCommandTemplate() As Threading.AsyncCommandTemplate
            Get
                Static config As AsyncCommandTemplate
                If config Is Nothing Then
                    config = New AsyncCommandTemplate
                    With config
                        '.TargetMethod = CreateDelegate(GetType(ConfigurationDelegate), Me, "Configuration")
                        .ExpirationTime = ConfigurationCommandExpirationTime
                        .IgnoreUnderlyingHandleOfTargetControl = True
                    End With
                End If
                Return config
            End Get
        End Property

        Public Sub Configuration(ByVal config As SensorConfiguration)
        End Sub
#End Region

#Region "       Uninitialization        "
        Public Overrides Sub Uninitialize()
            MyBase.Uninitialize()
            mCrossMatchVerifyCtrl.Uninitialize()
        End Sub
#End Region

#Region "       Capture     "
        Protected Friend mCaptureDone As Boolean
        Protected Friend mCaptureResult As Integer
        Private mTrueCaptureResultMethod As ResultMethod
        Private mCapturingFinger As New BodyParts

        Public Overrides ReadOnly Property CaptureCommandTemplate() As Threading.AsyncCommandTemplate
            Get
                Static Capture As AsyncCommandTemplate
                If Capture Is Nothing Then
                    Capture = New AsyncCommandTemplate
                    With Capture
                        .TargetMethod = CreateDelegate(GetType(ProcessDelegate), Me, "CaptureImage")
                        .ExpirationTime = CaptureCommandExpirationTime
                        .IgnoreUnderlyingHandleOfTargetControl = True
                    End With
                End If
                Return Capture
            End Get
        End Property

        Private Function CaptureImage() As Object
            Try
                mCaptureDone = False
                WritablePollingWasCanceled = False
                WritableIsTimeout = False

                Dim exIn As Exception
                If Not Open(exIn) Then
                    MarkAsOffline()
                    Throw New SensorException("CMV300: Cannot open sensor for recording.", exIn)
                End If

                While (Not mCaptureDone) AndAlso (Not PollingWasCanceled) AndAlso (Not IsTimeout)
                    WaitWithDoEvents(50, 10)
                End While

                'Must stop the CounterTimer soon after Capture returns from the reader
                StopCountdownTimerNow()

                ' if timed out or capture is Canceled, then throw exceptions
                If IsTimeout Or PollingWasCanceled Then
                    MarkAsOnline()
                    If IsTimeout Then Throw New CaptureTimeoutException("CMV300: Recording timeout.")
                    If PollingWasCanceled Then Throw New PollingCanceledException("CMV300: Recording Canceled.")
                End If

                With mCrossMatchVerifyCtrl
                    Dim ticks As Long = DateTime.Now.Ticks

                    Dim ImgWidth As Integer = .FullImageWidth
                    Dim ImgHeight As Integer = .FullImageHeight
                    Dim Imgobj As Object = .FullImage
                    Dim FingerprintImage As Bitmap = FullImageToBitmap(.FullImage)

                    Dim lResult As New CaptureResult
                    lResult.ImageProperties.Image = FingerprintImage
                    lResult.SensorProperties = mSensorProperties

                    Dim CaptureResultList As New CaptureResultCollection(1)
                    CaptureResultList.Results(CaptureResultList.Results.Length - 1) = lResult
                    WritableLatestThumbnail = FingerprintImage
                    Me.LastReviewImageAcceptable = True
                    MarkAsOnline()

                    Dim elapsed As Long = DateTime.Now.Ticks - ticks

                    Return CaptureResultList
                End With
            Catch ex As ThreadInterruptedException
                Dim cte As New CaptureTimeoutException
                cte.Sensor = Me
                cte.MachineNotes = "Capture timeout"
                Throw cte
            Finally
                mCrossMatchVerifyCtrl.ClearImage()
                MarkAsOnline()
                Close()
            End Try

        End Function

        Private Function Open(Optional ByRef rex As Exception = Nothing) As Boolean
            Try
                With mCrossMatchVerifyCtrl
                    .OpenScanner()
                    .ImageHandlingMode = CM_VERIFIERFINGERPRINTLib.IMAGE_HANDLING_MODE.SINLGE_FINGER_SLAP_SCANNER
                    .AutoFingerprintDetection = CM_VERIFIERFINGERPRINTLib.BOOL_EXT.TRUE_VALUE
                    .NoActivityTimeout = CaptureCommandExpirationTime
                    .set_LiveMode(0, CM_VERIFIERFINGERPRINTLib.LIVE_MODE.LIVE_MODE_ON)
                End With
            Catch ex As Exception
                rex = ex
                'return false for all sensor failure
                Return False
            End Try
            Return True
        End Function

        Private Sub Close()
            With mCrossMatchVerifyCtrl
                .set_LiveMode(0, CM_VERIFIERFINGERPRINTLib.LIVE_MODE.LIVE_MODE_OFF)
                .AutoFingerprintDetection = CM_VERIFIERFINGERPRINTLib.BOOL_EXT.FALSE_VALUE
                .CloseScanner()
            End With
            
        End Sub
#End Region

#Region "       Download      "
        'Protected Overrides Function CreateDownloadCommand(ByVal id As Guid) As AsyncCommand
        '    Dim DownloadCommand As New AsyncCommand(DownloadCommandTemplate)
        '    DownloadCommand.TargetMethodArg(0) = id
        '    Return DownloadCommand
        'End Function

        'Public Overrides ReadOnly Property DownloadCommandTemplate() As Threading.AsyncCommandTemplate
        '    Get
        '        Static download As AsyncCommandTemplate
        '        If download Is Nothing Then
        '            download = New AsyncCommandTemplate
        '            With download
        '                .TargetMethod = CreateDelegate(GetType(DownloadDelegate), Me, "DownloadImage")
        '                Dim args As Object() = {Guid.Empty}
        '                .TargetMethodArgs(args)
        '                .IgnoreUnderlyingHandleOfTargetControl = True
        '                .ExpirationTime = DownloadCommandExpirationTime
        '            End With
        '        End If
        '        Return download
        '    End Get
        'End Property
        'Private Delegate Function DownloadDelegate(ByVal id As Guid) As Object
        'Private Function DownloadImage(ByVal id As Guid) As Object
        'End Function
#End Region


        Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
            MyBase.OnLoad(e)
            WritablePollingWasCanceled = True
        End Sub

        Private Sub CancelSensorButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles CancelSensorButton.Click
            WritablePollingWasCanceled = True
        End Sub

        Public Function FullImageToBitmap(ByVal fullImageAsObject As Object) As Bitmap
            If EmptyPalette Is Nothing Then InitEmptyPalette()

            Dim fullImage As Array = CType(fullImageAsObject, Array)

            Try
                Dim maxRow As Integer = fullImage.GetUpperBound(0)
                Dim maxColumn As Integer = fullImage.GetUpperBound(1)
                Dim width As Integer = maxColumn + 1
                Dim height As Integer = maxRow + 1

                Dim imageAsBytes((maxColumn + 1) * (maxRow + 1) - 1) As Byte
                System.Buffer.BlockCopy(fullImage, 0, imageAsBytes, 0, fullImage.Length)

                Dim bmp As Bitmap = ConvertBytesAsObjectToBitmap(imageAsBytes, width, height)
                bmp.RotateFlip(RotateFlipType.Rotate270FlipNone)
                Return bmp
            Catch ex As Exception
                'Debugger.Break()
                MBARKDebugger.break()
            End Try

        End Function

        Private Sub mCrossMatchVerifyCtrl_DetectedFingerprints_VM5(ByVal sender As Object, ByVal e As AxCM_VERIFIERFINGERPRINTLib._IVerifierEvents_DetectedFingerprints_VM5Event) Handles mCrossMatchVerifyCtrl.DetectedFingerprints_VM5
            If e.status = CM_VERIFIERFINGERPRINTLib.FINGERPRINT_DETECTION_STATUS.FINGERPRINT_DETECTION_OK Then mCaptureDone = True
        End Sub
    End Class

End Namespace
