''  ---
''  License
''  ---
''
''  This software was developed at the National Institute of Standards and
''  Technology (NIST) by employees of the Federal Government in the course
''  of their official duties. Pursuant to title 17 Section 105 of the
''  United States Code, this software is not subject to copyright protection
''  and is in the public domain. NIST assumes no responsibility  whatsoever for
''  its use by other parties, and makes no guarantees, expressed or implied,
''  about its quality, reliability, or any other characteristic.
''
''  ---
''  Disclaimer
''  ---
''  This software was developed to facilitate multimodal biometric data collection
''  for the Department of Homeland Security in accordance with Section 303 of the 
''  Border Security Act, codified as 8 U.S.C. 1732.  Specific hardware and software 
''  products identified in this software were used in order to perform the data 
''  collection. In no case does such identification imply recommendation or endorsement 
''  by the National Institute of Standards and Technology, nor does it imply that the 
''  products and equipment identified are necessarily the best available for the purpose.
''

Option Strict On

Imports System.Drawing
Imports System.Windows.Forms

Imports SF = Syncfusion.Windows.Forms.Tools

Imports Mbark.UI

Namespace Mbark.Sensors

    Public Class FingerPickerControl
        Inherits BasePickerControl


#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
            UserNew()
        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 IndexCheckBox As System.Windows.Forms.CheckBox
        Friend WithEvents MiddleCheckBox As System.Windows.Forms.CheckBox
        Friend WithEvents RingCheckBox As System.Windows.Forms.CheckBox
        Friend WithEvents LittleCheckBox As System.Windows.Forms.CheckBox
        Friend WithEvents PalmCheckBox As System.Windows.Forms.CheckBox
        Public WithEvents ThumbCheckBox As System.Windows.Forms.CheckBox
        <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
            Me.IndexCheckBox = New System.Windows.Forms.CheckBox
            Me.MiddleCheckBox = New System.Windows.Forms.CheckBox
            Me.RingCheckBox = New System.Windows.Forms.CheckBox
            Me.LittleCheckBox = New System.Windows.Forms.CheckBox
            Me.PalmCheckBox = New System.Windows.Forms.CheckBox
            Me.ThumbCheckBox = New System.Windows.Forms.CheckBox
            Me.SuspendLayout()
            '
            'IndexCheckBox
            '
            Me.IndexCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleCenter
            Me.IndexCheckBox.FlatStyle = System.Windows.Forms.FlatStyle.System
            Me.IndexCheckBox.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!)
            Me.IndexCheckBox.Location = New System.Drawing.Point(16, 288)
            Me.IndexCheckBox.Name = "IndexCheckBox"
            Me.IndexCheckBox.Size = New System.Drawing.Size(19, 26)
            Me.IndexCheckBox.TabIndex = 1
            Me.IndexCheckBox.Text = "X"
            '
            'MiddleCheckBox
            '
            Me.MiddleCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleCenter
            Me.MiddleCheckBox.FlatStyle = System.Windows.Forms.FlatStyle.System
            Me.MiddleCheckBox.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!)
            Me.MiddleCheckBox.Location = New System.Drawing.Point(40, 288)
            Me.MiddleCheckBox.Name = "MiddleCheckBox"
            Me.MiddleCheckBox.Size = New System.Drawing.Size(19, 26)
            Me.MiddleCheckBox.TabIndex = 2
            Me.MiddleCheckBox.Text = "X"
            '
            'RingCheckBox
            '
            Me.RingCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleCenter
            Me.RingCheckBox.FlatStyle = System.Windows.Forms.FlatStyle.System
            Me.RingCheckBox.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!)
            Me.RingCheckBox.Location = New System.Drawing.Point(64, 288)
            Me.RingCheckBox.Name = "RingCheckBox"
            Me.RingCheckBox.Size = New System.Drawing.Size(19, 26)
            Me.RingCheckBox.TabIndex = 3
            Me.RingCheckBox.Text = "X"
            '
            'LittleCheckBox
            '
            Me.LittleCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleCenter
            Me.LittleCheckBox.FlatStyle = System.Windows.Forms.FlatStyle.System
            Me.LittleCheckBox.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!)
            Me.LittleCheckBox.Location = New System.Drawing.Point(112, 288)
            Me.LittleCheckBox.Name = "LittleCheckBox"
            Me.LittleCheckBox.Size = New System.Drawing.Size(19, 26)
            Me.LittleCheckBox.TabIndex = 4
            Me.LittleCheckBox.Text = "X"
            '
            'PalmCheckBox
            '
            Me.PalmCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleCenter
            Me.PalmCheckBox.FlatStyle = System.Windows.Forms.FlatStyle.System
            Me.PalmCheckBox.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!)
            Me.PalmCheckBox.Location = New System.Drawing.Point(88, 288)
            Me.PalmCheckBox.Name = "PalmCheckBox"
            Me.PalmCheckBox.Size = New System.Drawing.Size(19, 26)
            Me.PalmCheckBox.TabIndex = 5
            Me.PalmCheckBox.Text = "X"
            '
            'ThumbCheckBox
            '
            Me.ThumbCheckBox.BackColor = System.Drawing.SystemColors.Control
            Me.ThumbCheckBox.FlatStyle = System.Windows.Forms.FlatStyle.System
            Me.ThumbCheckBox.Location = New System.Drawing.Point(136, 288)
            Me.ThumbCheckBox.Name = "ThumbCheckBox"
            Me.ThumbCheckBox.RightToLeft = System.Windows.Forms.RightToLeft.No
            Me.ThumbCheckBox.Size = New System.Drawing.Size(19, 26)
            Me.ThumbCheckBox.TabIndex = 6
            '
            'FingerPickerControl
            '
            Me.BackColor = System.Drawing.SystemColors.Control
            Me.CausesValidation = False
            Me.Controls.Add(Me.ThumbCheckBox)
            Me.Controls.Add(Me.RingCheckBox)
            Me.Controls.Add(Me.PalmCheckBox)
            Me.Controls.Add(Me.MiddleCheckBox)
            Me.Controls.Add(Me.LittleCheckBox)
            Me.Controls.Add(Me.IndexCheckBox)
            Me.Name = "FingerPickerControl"
            Me.Size = New System.Drawing.Size(400, 472)
            Me.Controls.SetChildIndex(Me.IndexCheckBox, 0)
            Me.Controls.SetChildIndex(Me.LittleCheckBox, 0)
            Me.Controls.SetChildIndex(Me.MiddleCheckBox, 0)
            Me.Controls.SetChildIndex(Me.PalmCheckBox, 0)
            Me.Controls.SetChildIndex(Me.RingCheckBox, 0)
            Me.Controls.SetChildIndex(Me.ThumbCheckBox, 0)
            Me.ResumeLayout(False)

        End Sub

#End Region

        Private Sub UserNew()
            ' This gets set before Load(), which initializes the image
            PartImages(New Bitmap(Me.GetType(), "hand.png"), New Bitmap(Me.GetType(), "hand-disabled.png"))
        End Sub

        Private mIsLeft As Boolean = True
        Public Property IsLeft() As Boolean
            Get
                Return mIsLeft
            End Get
            Set(ByVal value As Boolean)
                mIsLeft = value
            End Set
        End Property

        Private mLeftSlapOnly As Boolean
        Public Property LeftSlapOnly As Boolean
            Get
                Return mLeftSlapOnly
            End Get
            Set(ByVal value As Boolean)
                mLeftSlapOnly = value
            End Set
        End Property

        Private mRightSlapOnly As Boolean
        Public Property RightSlapOnly As Boolean
            Get
                Return mRightSlapOnly
            End Get
            Set(ByVal value As Boolean)
                mRightSlapOnly = value
            End Set
        End Property

        Private mThumbsOnly As Boolean
        Public Property ThumbsOnly As Boolean
            Get
                Return mThumbsOnly
            End Get
            Set(ByVal value As Boolean)
                mThumbsOnly = value
            End Set
        End Property


        Private mBindingFromWireToControl As Boolean
        Protected Friend Overrides Sub BindFromWireToControl()

            If BodyPartsWire Is Nothing Then Return

            mBindingFromWireToControl = True

            With BodyPartsWire
                If IsLeft Then
                    If .Contains(BodyPart.LeftThumb) Then ThumbCheckBox.CheckState = CheckState.Checked Else ThumbCheckBox.CheckState = CheckState.Unchecked
                    If .Contains(BodyPart.LeftIndex) Then IndexCheckBox.CheckState = CheckState.Checked Else IndexCheckBox.CheckState = CheckState.Unchecked
                    If .Contains(BodyPart.LeftMiddle) Then MiddleCheckBox.CheckState = CheckState.Checked Else MiddleCheckBox.CheckState = CheckState.Unchecked
                    If .Contains(BodyPart.LeftRing) Then RingCheckBox.CheckState = CheckState.Checked Else RingCheckBox.CheckState = CheckState.Unchecked
                    If .Contains(BodyPart.LeftLittle) Then LittleCheckBox.CheckState = CheckState.Checked Else LittleCheckBox.CheckState = CheckState.Unchecked
                Else
                    If .Contains(BodyPart.RightThumb) Then ThumbCheckBox.CheckState = CheckState.Checked Else ThumbCheckBox.CheckState = CheckState.Unchecked
                    If .Contains(BodyPart.RightIndex) Then IndexCheckBox.CheckState = CheckState.Checked Else IndexCheckBox.CheckState = CheckState.Unchecked
                    If .Contains(BodyPart.RightMiddle) Then MiddleCheckBox.CheckState = CheckState.Checked Else MiddleCheckBox.CheckState = CheckState.Unchecked
                    If .Contains(BodyPart.RightRing) Then RingCheckBox.CheckState = CheckState.Checked Else RingCheckBox.CheckState = CheckState.Unchecked
                    If .Contains(BodyPart.RightLittle) Then LittleCheckBox.CheckState = CheckState.Checked Else LittleCheckBox.CheckState = CheckState.Unchecked
                End If

            End With

            mThumbState = ThumbCheckBox.CheckState
            mIndexState = IndexCheckBox.CheckState
            mMiddleState = MiddleCheckBox.CheckState
            mRingState = RingCheckBox.CheckState
            mLittleState = LittleCheckBox.CheckState


            RefreshCheckboxes()
            mBindingFromWireToControl = False


        End Sub

        Private Sub BindFromControlToWire()

            If BodyPartsWire Is Nothing Then Return

            With BodyPartsWire
                If IsLeft Then
                    If ThumbCheckBox.CheckState = CheckState.Checked Then .Add(BodyPart.LeftThumb) Else .Remove(BodyPart.LeftThumb)
                    If IndexCheckBox.CheckState = CheckState.Checked Then .Add(BodyPart.LeftIndex) Else .Remove(BodyPart.LeftIndex)
                    If MiddleCheckBox.CheckState = CheckState.Checked Then .Add(BodyPart.LeftMiddle) Else .Remove(BodyPart.LeftMiddle)
                    If RingCheckBox.CheckState = CheckState.Checked Then .Add(BodyPart.LeftRing) Else .Remove(BodyPart.LeftRing)
                    If LittleCheckBox.CheckState = CheckState.Checked Then .Add(BodyPart.LeftLittle) Else .Remove(BodyPart.LeftLittle)
                Else
                    If ThumbCheckBox.CheckState = CheckState.Checked Then .Add(BodyPart.RightThumb) Else .Remove(BodyPart.RightThumb)
                    If IndexCheckBox.CheckState = CheckState.Checked Then .Add(BodyPart.RightIndex) Else .Remove(BodyPart.RightIndex)
                    If MiddleCheckBox.CheckState = CheckState.Checked Then .Add(BodyPart.RightMiddle) Else .Remove(BodyPart.RightMiddle)
                    If RingCheckBox.CheckState = CheckState.Checked Then .Add(BodyPart.RightRing) Else .Remove(BodyPart.RightRing)
                    If LittleCheckBox.CheckState = CheckState.Checked Then .Add(BodyPart.RightLittle) Else .Remove(BodyPart.RightLittle)
                End If
            End With


        End Sub

        Protected Overrides Sub OnLoad(ByVal e As EventArgs)
            MyBase.OnLoad(e)
            If InDesignMode(Me) Then Return
            RefreshCheckboxes()
        End Sub

        Private Shared LittleTip As New Point(136 - 4, 57 - 10)
        Private Shared RingTip As New Point(190 - 4, 33 - 10)
        Private Shared MiddleTip As New Point(242 - 4, 12 - 10)
        Private Shared IndexTip As New Point(290 - 4, 38 - 10)
        Private Shared ThumbTip As New Point(282, 168 - 10)
        Private Shared PalmCenter As New Point(67 - 4, 281 - 10)

        Private Sub PlaceCheckBox(ByVal checkBox As CheckBox, ByVal loc As Point)

            Dim newPoint As Point = MainPictureBox.RemapImagePoint(loc)

            checkBox.Size = GlobalUISettings.ControlSizes.CheckBox

            newPoint.Y += DockPadding.Top - checkBox.Height
            newPoint.X -= CInt(checkBox.Width / 2.0!)
            newPoint.X += DockPadding.Left

            checkBox.Location = newPoint

        End Sub

        Protected Overrides Sub LayoutCheckboxes()

            ' See if we need to add a little padding at the top
            Dim newMiddle As Point = MainPictureBox.RemapImagePoint(MiddleTip)
            If newMiddle.Y < IndexCheckBox.Height Then
                DockPadding.Top = IndexCheckBox.Height - newMiddle.Y
            Else
                DockPadding.Top = 0
            End If

            Dim newIndex As Point = MainPictureBox.RemapImagePoint(IndexTip)
            If IsLeft AndAlso newIndex.X > (MainPictureBox.Width - IndexCheckBox.Width / 2.0!) Then
                DockPadding.Right = CInt(IndexCheckBox.Width / 2.0! - (MainPictureBox.Width - newIndex.X))
            ElseIf newIndex.X < IndexCheckBox.Width Then
                DockPadding.Left = CInt(IndexCheckBox.Width / 2.0!) - newIndex.X
            Else
                DockPadding.Left = 0
                DockPadding.Right = 0
            End If

            PlaceCheckBox(ThumbCheckBox, ThumbTip)
            PlaceCheckBox(IndexCheckBox, IndexTip)
            PlaceCheckBox(MiddleCheckBox, MiddleTip)
            PlaceCheckBox(RingCheckBox, RingTip)
            PlaceCheckBox(LittleCheckBox, LittleTip)
            PlaceCheckBox(PalmCheckBox, PalmCenter)

        End Sub

        Protected Overrides Sub OnLayout(ByVal levent As LayoutEventArgs)
            MyBase.OnLayout(levent)

            If IsLeft Then
                FooterLabel.Text = "Left Hand" ' i18n
                MainPictureBox.Backwards = False
            Else
                FooterLabel.Text = "Right Hand"
                MainPictureBox.Backwards = True
            End If
            MainPictureBox.Refresh()
            LayoutCheckboxes()

        End Sub

        Private mThumbState As CheckState
        Private mIndexState As CheckState
        Private mMiddleState As CheckState
        Private mRingState As CheckState
        Private mLittleState As CheckState
        Private mPalmState As CheckState


        Private Sub ThumbCheckBox_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ThumbCheckBox.CheckedChanged
            If mBindingFromWireToControl Then Return
            If Not mHandlingPalmCheckBox Then mThumbState = ThumbCheckBox.CheckState
            RefreshCheckboxes()
            BindFromControlToWire()
        End Sub

        Private Sub IndexCheckBox_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IndexCheckBox.CheckedChanged
            If mBindingFromWireToControl Then Return
            If Not mHandlingPalmCheckBox Then mIndexState = IndexCheckBox.CheckState
            RefreshCheckboxes()
            BindFromControlToWire()
        End Sub

        Private Sub LittleCheckBox_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LittleCheckBox.CheckedChanged
            If mBindingFromWireToControl Then Return
            If Not mHandlingPalmCheckBox Then mLittleState = LittleCheckBox.CheckState
            RefreshCheckboxes()
            BindFromControlToWire()
        End Sub

        Private Sub RingCheckBox_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RingCheckBox.CheckedChanged
            If mBindingFromWireToControl Then Return
            If Not mHandlingPalmCheckBox Then mRingState = RingCheckBox.CheckState
            RefreshCheckboxes()
            BindFromControlToWire()
        End Sub

        Private Sub MiddleCheckBox_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MiddleCheckBox.CheckedChanged
            If mBindingFromWireToControl Then Return
            If Not mHandlingPalmCheckBox Then mMiddleState = MiddleCheckBox.CheckState
            RefreshCheckboxes()
            BindFromControlToWire()
        End Sub


        Private mAllFingersManuallyChecked As Boolean
        Private mAllFingersChecked As Boolean
        Private mInsideRefreshCheckboxes As Boolean
        Protected Overrides Sub RefreshCheckboxes()

            If mInsideRefreshCheckboxes Then Return
            mInsideRefreshCheckboxes = True


            '
            ' First, we see if all the boxes were manually checked
            '
            If mThumbState = CheckState.Checked AndAlso _
               mIndexState = CheckState.Checked AndAlso _
               mMiddleState = CheckState.Checked AndAlso _
               mRingState = CheckState.Checked AndAlso _
               mLittleState = CheckState.Checked Then
                mAllFingersManuallyChecked = True
            Else
                mAllFingersManuallyChecked = False
            End If

            If ThumbCheckBox.CheckState = CheckState.Checked AndAlso _
               IndexCheckBox.CheckState = CheckState.Checked AndAlso _
               MiddleCheckBox.CheckState = CheckState.Checked AndAlso _
               RingCheckBox.CheckState = CheckState.Checked AndAlso _
               LittleCheckBox.CheckState = CheckState.Checked Then
                mAllFingersChecked = True
            Else
                mAllFingersChecked = False
            End If


            If mHandlingPalmCheckBox Then
                ' 
                ' Respond to a change in the palm check box
                ' 
                If mPalmState = CheckState.Checked Then

                    ' Using .BeginUpdate caches the updates so they don't all happen at once
                    BodyPartsWire.BeginUpdate()
                    ThumbCheckBox.CheckState = CheckState.Checked
                    IndexCheckBox.CheckState = CheckState.Checked
                    MiddleCheckBox.CheckState = CheckState.Checked
                    RingCheckBox.CheckState = CheckState.Checked
                    LittleCheckBox.CheckState = CheckState.Checked
                    BodyPartsWire.EndUpdate()

                    ThumbCheckBox.Enabled = False
                    IndexCheckBox.Enabled = False
                    MiddleCheckBox.Enabled = False
                    RingCheckBox.Enabled = False
                    LittleCheckBox.Enabled = False
                    PalmCheckBox.Enabled = MyBase.Enabled

                Else

                    If Not BodyPartsWire Is Nothing Then BodyPartsWire.BeginUpdate()
                    ThumbCheckBox.CheckState = mThumbState
                    IndexCheckBox.CheckState = mIndexState
                    MiddleCheckBox.CheckState = mMiddleState
                    RingCheckBox.CheckState = mRingState
                    LittleCheckBox.CheckState = mLittleState
                    If Not BodyPartsWire Is Nothing Then BodyPartsWire.EndUpdate()

                    ThumbCheckBox.Enabled = MyBase.Enabled
                    IndexCheckBox.Enabled = MyBase.Enabled
                    MiddleCheckBox.Enabled = MyBase.Enabled
                    RingCheckBox.Enabled = MyBase.Enabled
                    LittleCheckBox.Enabled = MyBase.Enabled

                End If

            Else
                '
                ' Respond to a change in some other finger
                '

                If mAllFingersManuallyChecked Then
                    PalmCheckBox.CheckState = CheckState.Checked
                    PalmCheckBox.Enabled = False
                Else
                    PalmCheckBox.Enabled = Enabled
                    Dim enableFingers As Boolean

                    If mAllFingersChecked Then
                        PalmCheckBox.CheckState = CheckState.Checked
                    Else
                        PalmCheckBox.CheckState = CheckState.Unchecked
                        ThumbCheckBox.Enabled = Enabled
                        IndexCheckBox.Enabled = Enabled
                        MiddleCheckBox.Enabled = Enabled
                        RingCheckBox.Enabled = Enabled
                        LittleCheckBox.Enabled = Enabled
                    End If

                End If

            End If


            ThumbCheckBox.Refresh()
            IndexCheckBox.Refresh()
            MiddleCheckBox.Refresh()
            RingCheckBox.Refresh()
            LittleCheckBox.Refresh()
            PalmCheckBox.Refresh()
            mInsideRefreshCheckboxes = False
            Return


        End Sub



        Private mHandlingPalmCheckBox As Boolean
        Private Sub PalmCheckBox_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PalmCheckBox.CheckedChanged
            mPalmState = PalmCheckBox.CheckState

            mHandlingPalmCheckBox = True
            RefreshCheckboxes()
            mHandlingPalmCheckBox = False

            BindFromControlToWire()
        End Sub
        'reset all check box - un-check all check box when new session starting
        Public Sub ResetFingerPickerControl()
            ThumbCheckBox.Checked = False
            IndexCheckBox.Checked = False
            MiddleCheckBox.Checked = False
            RingCheckBox.Checked = False
            LittleCheckBox.Checked = False
            PalmCheckBox.Checked = False
        End Sub

        Protected Overrides Sub OnEnabledChanged(ByVal e As EventArgs)
            MyBase.OnEnabledChanged(e)
            RefreshCheckboxes()
        End Sub

        Public Overrides Sub Refresh()
            MyBase.Refresh()
            Me.RefreshCheckboxes()
        End Sub



    End Class

End Namespace