VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "ArmCheckList"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
'common database access instance
Private mo_Db As ARMSYSCOMLib.ArmDb
'item collection
Private mo_Items As Collection
'reference to parent checkview
Private mo_CheckView As ArmCheckView
'reference to microsoft ListView control
Private mo_ListView As ListView
'flag if checklist is loaded or not
Private mb_Loaded As Boolean
'caption for checklist, which is displayed in combo
Public Caption As String
'name of checklist which allows access to checklist from framework
Public Name As String
'flag if true, checklist caption is displayed in combo
Public In_Combo As Boolean
'priority for this checklist
Public Priority As Long
'request which is responsible for loading this checklist
Public RequestLoad As String
'request which save checked item into database
Public RequestCheck As String
'request which save unchecked items in database
Public RequestUnCheck As String
'if true this checklist is readonly for user (not framework)
Public ReadOnly As Boolean
'checklist can have none, one ore many items checked
Public One_Or_Many As Integer
'behaviour of checklist is like radio buttons
Public Radio_List As Boolean
'mode of checklist - view or edit
Public Mode As ListMode
'reference to the one and only view checklist
Public ViewCheckList As ArmCheckList
'array of data fields which are stored in items for this checklist
Public DataFields As Variant
'array of visible fields which will be displayed in checklist
Public Visible_Fields As Variant
'array of columns widths in checkview
Public Visible_Fields_Width As Variant
'indexes to data array in item info
Public Visible_FieldsIndex As Variant
'array of link key fields
Public Link_Key_Fields As Variant
'array of indexes to link fields (index to data array in item info)
Public Link_Key_FieldsIndex As Variant
'array of key fiels
Public KeyFields As Variant
'array of indexes to key fields
Public KeyFieldsIndex As Variant
'captions for columns
Public ColumnCaptions As Variant
'order of display of items - 0 - first checked then unchecked, 1 - loaded order
Public DisplayOrder As Long
'reference to trace object
Public Trace As Object
'this is additional data fields, which are valid for all item in check list
'I didn't add it to data array in item info, because they are the same for entire list
Public CommonRoleFields As Variant
'array of additional common values
Public CommonRoleValues As Variant

'mode type enumeration
Public Enum ListMode
  clModeView
  clModeEdit
End Enum

'******************************************************************************
' public properties
'******************************************************************************

Public Property Set ArmCheckView(lo_Value As ArmCheckView)
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:ArmCheckView_Set")
#End If
  
  Set mo_CheckView = lo_Value

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:ArmCheckView_Set")
#End If
End Property

'reference to microsoft listview
Public Property Set ListView(lo_Value As ListView)
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:ListView_Set")
#End If
  
  Set mo_ListView = lo_Value

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:ListView_Set")
#End If
End Property

'reference to armdb component database access
Public Property Set ArmDb(lo_NewValue As ARMSYSCOMLib.ArmDb)
  
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:ArmDB_Set")
#End If
  
  Set mo_Db = lo_NewValue

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:ArmDB_Set")
#End If
End Property

Public Property Get ArmDb() As ARMSYSCOMLib.ArmDb

#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:ArmDB_Get")
#End If
  
  Set ArmDb = mo_Db

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:ArmDB_Get")
#End If
End Property

'reference to items collection
Public Property Get Items() As Collection
  
  Set Items = mo_Items
End Property

'number of items in collection
Public Property Get Count() As Long
  
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:Count_Get")
#End If
  
  Count = mo_Items.Count

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:Count_Get")
#End If
End Property

'get number of checked items in checklist
Public Property Get CheckedCount() As Long
Dim ll_Count As Long
Dim lo_ItemInfo As ArmItemInfo
  
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:CheckedCount_Get")
#End If
  
  ll_Count = 0
  For Each lo_ItemInfo In mo_Items
    If lo_ItemInfo.CurrentChecked Then ll_Count = ll_Count + 1
  Next
  CheckedCount = ll_Count

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:CheckedCount_Get")
#End If
End Property

'determine if checklist is loaded or not
Public Property Get Loaded() As Boolean

#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:Loaded_Get")
#End If
  
  Loaded = mb_Loaded

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:Loaded_Get")
#End If
End Property

'******************************************************************************
' public methods
'******************************************************************************
'standard armstrong constructor
Public Sub Load_A_COM()
  
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:Load_A_COM")
#End If
  
  Set mo_Items = New Collection
  Mode = clModeEdit
  Radio_List = False
  One_Or_Many = 2
  ReadOnly = False
  mb_Loaded = False

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:Load_A_COM")
#End If
End Sub

'standard armstrong destructor
Public Sub Unload_A_COM()
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:Unload_A_COM")
#End If
  
  Set mo_Items = Nothing
  Set mo_Db = Nothing

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:Unload_A_COM")
#End If
End Sub

'load all items valid for this checklist from cursor, automaticaly check items if we load
'view checklist and uncheck if we load edit checklist
Public Function LoadListCursor(al_Cursor As Long) As Boolean
Dim lo_ItemInfo As ArmItemInfo
Dim lb_Result As Boolean
Dim lv_Data As Variant

  On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:LoadListCursor")
#End If
  
  lb_Result = False
  Call mo_CheckView.SetMousePointer(False)
  Call ClearList
  If al_Cursor Then
    Call mo_Db.First(al_Cursor)
    Do While Not mo_Db.EOF(al_Cursor)
      lv_Data = mo_Db.GetFields(al_Cursor, DataFields)
      If IsEmpty(lv_Data) Then
        GoTo ErrorHandler
      Else
        Call AddItemInfo(lv_Data, (Mode = clModeView), (Mode = clModeView))
      End If
      Call mo_Db.Next(al_Cursor)
    Loop
    lb_Result = True
    mb_Loaded = True
  End If
  Call mo_CheckView.SetMousePointer(True)
  LoadListCursor = lb_Result
  
#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:LoadListCursor")
#End If
  Exit Function
ErrorHandler:
  Call mo_CheckView.SetMousePointer(True)
  LoadListCursor = False
#If CompDebugCV Then
  Call Trace.WriteTraceError("ArmCheckList:LoadListCursor")
#End If
End Function

'get reference to iteminfo according its key value
Public Function GetItem(av_Key As Variant) As ArmItemInfo
Dim ll_KeyIndex As Long
Dim lv_Key As Variant
Dim lb_Found As Boolean
Dim lo_ItemInfo As ArmItemInfo

#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:GetItem")
#End If
  
  Set GetItem = Nothing
  If IsArray(av_Key) Then
    If UBound(av_Key) <> UBound(KeyFieldsIndex) Then GoTo ErrorHandler
  Else
    GoTo ErrorHandler
  End If
  
  For Each lo_ItemInfo In mo_Items
    lv_Key = GetItemKey(lo_ItemInfo)
    lb_Found = True
    For ll_KeyIndex = 0 To UBound(av_Key)
      If CStr(av_Key(ll_KeyIndex)) <> CStr(lv_Key(ll_KeyIndex)) Then
        lb_Found = False
        Exit For
      End If
    Next ll_KeyIndex
    If lb_Found Then
      Set GetItem = lo_ItemInfo
      Exit For
    End If
  Next lo_ItemInfo

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:GetItem")
#End If
  Exit Function
ErrorHandler:
#If CompDebugCV Then
  Call Trace.WriteTraceError("ArmCheckList:GetItem")
#End If
End Function

'change item status - checked or unchecked, use checklist rules
Public Function ChangeItemValue(ByVal ao_ItemInfo As ArmItemInfo, ab_Value As Boolean, Optional ab_Internal = False) As Boolean
Dim ll_CheckedCount As Long
Dim lb_Result As Boolean
  
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:ChangeItemValue")
#End If
  
  lb_Result = False
  
  If ao_ItemInfo Is Nothing Then GoTo ExitChange
  
  If Not ab_Internal Then
    If ReadOnly Then
      GoTo ExitChange
    End If
  
    If ao_ItemInfo.ReadOnly Then GoTo ExitChange
  End If
  
  ll_CheckedCount = CheckedCount
  Select Case One_Or_Many
  Case 0
    'we cannot check any item
    If ab_Value Then
      lb_Result = False
    Else
      'we can uncheck anything we want
      ao_ItemInfo.CurrentChecked = ab_Value
      lb_Result = True
    End If
  Case 1
    If ab_Value Then
      If Radio_List Then
        'there can be only one item check so first uncheck all checked
        Call UnCheckAll
        ao_ItemInfo.CurrentChecked = ab_Value
        lb_Result = True
      Else
        lb_Result = False
        If (ll_CheckedCount = 0) Or (ao_ItemInfo.CurrentChecked) Then
          ao_ItemInfo.CurrentChecked = ab_Value
          lb_Result = True
        End If
      End If
    Else
      'we cannot uncheck last one checked item for this radio check list
      If (ll_CheckedCount = 1) And ao_ItemInfo.CurrentChecked And Radio_List Then
        lb_Result = False
      Else
        ao_ItemInfo.CurrentChecked = ab_Value
        lb_Result = True
      End If
    End If
  Case Else
    ao_ItemInfo.CurrentChecked = ab_Value
    lb_Result = True
  End Select
  
  If lb_Result Then
    Call RefreshList
    If mo_CheckView.Synchronize_View And (Not (ViewCheckList Is Nothing)) Then
      Call UpdateViewList(ViewCheckList)
    End If
  End If
  ChangeItemValue = lb_Result
  
ExitChange:
#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:ChangeItemValue")
#End If
End Function

'add all checked items into listview
Private Sub DisplayCheckedItems()
Dim lo_ItemInfo As ArmItemInfo

#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:DisplayCheckedItems")
#End If
  
  For Each lo_ItemInfo In mo_Items
    If lo_ItemInfo.CurrentChecked Then Call AddListItem(lo_ItemInfo)
  Next

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:DisplayCheckedItems")
#End If
End Sub

'add all unchecked item into listview
Private Sub DisplayUncheckedItems()
Dim lo_ItemInfo As ArmItemInfo

#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:DisplayUncheckedItems")
#End If
  
  For Each lo_ItemInfo In mo_Items
    If Not lo_ItemInfo.CurrentChecked Then Call AddListItem(lo_ItemInfo)
  Next

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:DisplayUncheckedItems")
#End If
End Sub

'add all items into checklist, order is the same like they are loaded
Private Sub DisplayAllItems()
Dim lo_ItemInfo As ArmItemInfo

#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:DisplayAllItems")
#End If
  
  For Each lo_ItemInfo In mo_Items
    Call AddListItem(lo_ItemInfo)
  Next

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:DisplayAllItems")
#End If
End Sub

'display checklist in microsoft listview
Public Function DisplayList() As Boolean
Dim ll_Index As Long
Dim lo_ItemInfo As ArmItemInfo
Dim lo_ListItem As ListItem

On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:DisplayList")
#End If
  
  Call mo_CheckView.SetRedraw(mo_ListView.hwnd, False)
  Call mo_CheckView.SetMousePointer(False)
  Call ClearListView
  Call InitListColumns
  'display checkboxes in edit list
  mo_CheckView.Checkboxes = (Mode = clModeEdit)
  
  If Mode = clModeView Then
    Call DisplayCheckedItems
  Else
    If DisplayOrder = 0 Then
      'first display checked items
      Call DisplayCheckedItems
      'then display unchecked items
      Call DisplayUncheckedItems
    Else
      Call DisplayAllItems
    End If
  End If
  DisplayList = True
  Call mo_CheckView.SetMousePointer(True)
  Call mo_CheckView.SetRedraw(mo_ListView.hwnd, True)
  
#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:DisplayList")
#End If
  Exit Function
ErrorHandler:
  DisplayList = False
  Call mo_CheckView.SetMousePointer(True)
  Call mo_CheckView.SetRedraw(mo_ListView.hwnd, True)
#If CompDebugCV Then
  Call Trace.WriteTraceError("ArmCheckList:DisplayList")
#End If
End Function

'refresh items status in checklist, don't change item order
Public Function RefreshList() As Boolean
Dim lo_ListItem As ListItem

#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:RefreshList")
#End If
  
  For Each lo_ListItem In mo_ListView.ListItems
    lo_ListItem.Checked = lo_ListItem.Tag.CurrentChecked
  Next

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:RefreshList")
#End If
End Function

'get key array of particular iteminfo instance
Public Function GetItemKey(ao_ItemInfo As ArmItemInfo) As Variant
Dim lv_Key As Variant
Dim ll_KeyIndex As Long

#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:GetItemKey")
#End If
  
  If Not (ao_ItemInfo Is Nothing) Then
    ReDim lv_Key(UBound(KeyFieldsIndex))
    For ll_KeyIndex = 0 To UBound(KeyFieldsIndex)
      lv_Key(ll_KeyIndex) = ao_ItemInfo.GetData(KeyFieldsIndex(ll_KeyIndex))
    Next
  End If
  GetItemKey = lv_Key

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:GetItemKey")
#End If
End Function

'get key array of iteminfo with index al_index
Public Function GetKey(al_Index As Long) As Variant

#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:GetKey")
#End If
  
  GetKey = Empty
  If (al_Index >= 1) And (al_Index <= mo_Items.Count) Then
    GetKey = GetItemKey(mo_Items(al_Index))
  End If

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:GetKey")
#End If
End Function

'update edit checklist from this instance (should be view)
Public Function UpdateEditList(ao_CheckEditList As ArmCheckList) As Boolean
Dim lb_Found As Boolean
Dim ll_LinkKeyIndex As Long
Dim lo_ItemView As ArmItemInfo, lo_ItemEdit As ArmItemInfo

#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:UpdateEditList")
#End If
  
  Call ao_CheckEditList.InitList
  For Each lo_ItemView In mo_Items
  
    lb_Found = False
    For Each lo_ItemEdit In ao_CheckEditList.Items
      lb_Found = True
      For ll_LinkKeyIndex = 0 To UBound(Link_Key_FieldsIndex)
        If CStr(lo_ItemView.GetData(Link_Key_FieldsIndex(ll_LinkKeyIndex))) <> _
           CStr(lo_ItemEdit.GetData(ao_CheckEditList.Link_Key_FieldsIndex(ll_LinkKeyIndex))) Then
           lb_Found = False
           Exit For
        End If
      Next
      If lb_Found Then
        lo_ItemEdit.CurrentChecked = True
        lo_ItemEdit.OriginalChecked = True
      End If
    Next lo_ItemEdit
  Next lo_ItemView
  UpdateEditList = True

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:UpdateEditList")
#End If
End Function

'update view checklist from this instance (should be edit)
Public Function UpdateViewList(ao_CheckViewList As ArmCheckList) As Boolean
Dim lb_Found As Boolean
Dim ll_LinkKeyIndex As Long, ll_Index As Long
Dim lo_ItemView As ArmItemInfo, lo_ItemEdit As ArmItemInfo
Dim lv_Data As Variant

#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:UpdateViewList")
#End If
  
  For Each lo_ItemEdit In mo_Items
    lb_Found = False
    For Each lo_ItemView In ao_CheckViewList.Items
      lb_Found = True
      For ll_LinkKeyIndex = 0 To UBound(Link_Key_FieldsIndex)
        If CStr(lo_ItemEdit.GetData(Link_Key_FieldsIndex(ll_LinkKeyIndex))) <> _
           CStr(lo_ItemView.GetData(ao_CheckViewList.Link_Key_FieldsIndex(ll_LinkKeyIndex))) Then
           lb_Found = False
           Exit For
        End If
      Next
      If lb_Found Then Exit For
    Next lo_ItemView
    
    If lb_Found Then
      'if item is found in view list then update checked status
      lo_ItemView.CurrentChecked = lo_ItemEdit.CurrentChecked
    Else
      'if item is not found in view list then add it
      If lo_ItemEdit.CurrentChecked Then
        ReDim lv_Data(UBound(ao_CheckViewList.DataFields))
        For ll_Index = 0 To UBound(lv_Data)
          lv_Data(ll_Index) = lo_ItemEdit.GetData(GetFieldIndex(ao_CheckViewList.DataFields(ll_Index)))
        Next
        Call ao_CheckViewList.AddItemInfo(lv_Data, False, True)
      End If
    End If
  Next lo_ItemEdit
  If StrComp(mo_CheckView.GetVisibleList, ao_CheckViewList.Name, vbTextCompare) = 0 Then
    Call ao_CheckViewList.DisplayList
  End If
  UpdateViewList = True

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:UpdateViewList")
#End If
End Function

'uncheck all items in this checklist
Public Function UnCheckAll() As Boolean
Dim lo_ItemInfo As ArmItemInfo

On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:UnCheckAll")
#End If
  
  For Each lo_ItemInfo In mo_Items
    lo_ItemInfo.CurrentChecked = False
  Next
  Call RefreshList
  If mo_CheckView.Synchronize_View And (Not (ViewCheckList Is Nothing)) Then
    Call UpdateViewList(ViewCheckList)
  End If
  UnCheckAll = True
  
#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:UnCheckAll")
#End If
  Exit Function
ErrorHandler:
  UnCheckAll = False
#If CompDebugCV Then
  Call Trace.WriteTraceError("ArmCheckList:UnCheckAll")
#End If
End Function

'undo all items in this checklist
Public Function Undo() As Boolean
Dim lo_ItemInfo As ArmItemInfo

On Error GoTo ErrorHandler
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:Undo")
#End If
  
  For Each lo_ItemInfo In mo_Items
    lo_ItemInfo.CurrentChecked = lo_ItemInfo.OriginalChecked
  Next
  Undo = True
  
#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:Undo")
#End If
  Exit Function
ErrorHandler:
  Undo = False
#If CompDebugCV Then
  Call Trace.WriteTraceError("ArmCheckList:Undo")
#End If
End Function

'get array of all checked item keys
Public Function CheckedKeys() As Variant
Dim lv_Keys As Variant
Dim ll_Count As Long, ll_Index As Long
Dim lo_ItemInfo As ArmItemInfo
  
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:CheckedKeys")
#End If
  
  lv_Keys = Empty
  ll_Count = CheckedCount
  If ll_Count > 0 Then
    ReDim lv_Keys(ll_Count - 1)
    ll_Index = 0
    For Each lo_ItemInfo In mo_Items
      If lo_ItemInfo.CurrentChecked Then
        lv_Keys(ll_Index) = GetItemKey(lo_ItemInfo)
        ll_Index = ll_Index + 1
      End If
    Next
  End If
  CheckedKeys = lv_Keys

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:CheckedKeys")
#End If
End Function

'init checklist if edit uncheck list, if view delete all items from checklist
Public Function InitList() As Boolean
Dim lo_ItemInfo As ArmItemInfo
  
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:InitList")
#End If
  
  If Mode = clModeEdit Then
    For Each lo_ItemInfo In mo_Items
      Call lo_ItemInfo.Clear
    Next
    InitList = True
  Else
    InitList = ClearList
  End If

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:InitList")
#End If
End Function

'remove all items from checklist
Public Function ClearList() As Boolean
  
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:ClearList")
#End If
  
  Do While mo_Items.Count > 0
    Call mo_Items.Remove(1)
  Loop
  ClearList = True

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:ClearList")
#End If
End Function

'add iteminfo instance to internal checklist collection
Public Function AddItemInfo(av_Data As Variant, ab_OriginalChecked As Boolean, ab_CurrentChecked As Boolean) As Boolean
Dim lo_ItemInfo As ArmItemInfo

  Set lo_ItemInfo = New ArmItemInfo
  Set lo_ItemInfo.CheckList = Me
  lo_ItemInfo.Data = av_Data
  lo_ItemInfo.OriginalChecked = ab_OriginalChecked
  lo_ItemInfo.CurrentChecked = ab_CurrentChecked
  Call mo_Items.Add(lo_ItemInfo)
  AddItemInfo = True
End Function

'******************************************************************************
' private methods
'******************************************************************************
'get index of field with name of as_name inside iteminfo
Private Function GetFieldIndex(ByVal as_Name As String) As Long
Dim ll_Index As Long, ll_Result As Long
  
  ll_Result = -1
  For ll_Index = 0 To UBound(CommonRoleFields)
    If StrComp(as_Name, CommonRoleFields(ll_Index), vbTextCompare) = 0 Then
      ll_Result = UBound(DataFields) + ll_Index + 1
      Exit For
    End If
  Next
  If ll_Result = -1 Then
    For ll_Index = 0 To UBound(DataFields)
      If StrComp(DataFields(ll_Index), as_Name, vbTextCompare) = 0 Then
        ll_Result = ll_Index
        Exit For
      End If
    Next
  End If
  GetFieldIndex = ll_Result
End Function

'init array of field indexes in destination variant from source field names
Private Function InitFieldsIndex(ByRef av_SrcFieldNames As Variant, ByRef av_DstFieldIndexes As Variant) As Boolean
Dim ll_Index As Long

  ReDim av_DstFieldIndexes(UBound(av_SrcFieldNames))
  For ll_Index = 0 To UBound(av_SrcFieldNames)
    If IsNumeric(av_SrcFieldNames(ll_Index)) Then
      av_DstFieldIndexes(ll_Index) = CLng(av_SrcFieldNames(ll_Index))
    Else
      av_DstFieldIndexes(ll_Index) = GetFieldIndex(av_SrcFieldNames(ll_Index))
    End If
  Next
  InitFieldsIndex = True
End Function

'init all internal indexes
Public Function InitIndexes()
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:InitIndexes")
#End If
  
  Call InitFieldsIndex(Visible_Fields, Visible_FieldsIndex)
  Call InitFieldsIndex(Link_Key_Fields, Link_Key_FieldsIndex)
  Call InitFieldsIndex(KeyFields, KeyFieldsIndex)

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:InitIndexes")
#End If
End Function

'clear microsofts listview
Private Sub ClearListView()
  
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:ClearListView")
#End If
  
  mo_ListView.ListItems.Clear

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:ClearListView")
#End If
End Sub

'add iteminfo instance into our microsoft ListView
Private Function AddListItem(ByRef lo_ItemInfo As ArmItemInfo) As ListItem
Dim lo_ListItem As ListItem
Dim ll_Index As Long

On Error GoTo ErrorHandler
  Set lo_ListItem = mo_ListView.ListItems.Add
  Set lo_ItemInfo.CheckList = Me
  If lo_ItemInfo.ReadOnly Then lo_ListItem.ForeColor = vbGrayText
  
  lo_ListItem.Checked = lo_ItemInfo.CurrentChecked
  For ll_Index = 0 To UBound(Visible_Fields)
    If ll_Index = 0 Then
      lo_ListItem.Text = lo_ItemInfo.GetData(Visible_FieldsIndex(ll_Index))
    Else
      Call lo_ListItem.ListSubItems.Add(, , CStr(lo_ItemInfo.GetData(Visible_FieldsIndex(ll_Index))), , "")
    End If
  Next
  Set lo_ListItem.Tag = lo_ItemInfo
  Set AddListItem = lo_ListItem
  Exit Function
ErrorHandler:
  Set AddListItem = Nothing
#If CompDebugCV Then
  Call Trace.WriteTraceError("ArmCheckList:AddListItem")
#End If
End Function

'get columns (field) caption acording field name
Private Function GetFieldCaption(ByVal as_FieldName As String) As String
Dim ll_Index As Long
  
#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:GetFieldCaption")
#End If
  
  GetFieldCaption = ""
  If IsArray(ColumnCaptions) Then
    For ll_Index = 0 To ((UBound(ColumnCaptions) + 1) \ 2) - 1
      If StrComp(as_FieldName, ColumnCaptions(ll_Index * 2), vbTextCompare) = 0 Then
        GetFieldCaption = ColumnCaptions(ll_Index * 2 + 1)
        Exit For
      End If
    Next
  End If

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:GetFieldCaption")
#End If
End Function

'initialize columns in listview in checkview and column captions
Private Function InitListColumns() As Boolean
Dim ll_Index As Long

#If CompDebugCV Then
  Call Trace.WriteTraceProc(True, "ArmCheckList:InitListColumns")
#End If
  
  mo_CheckView.ColumnHeaders.Clear
  For ll_Index = 0 To UBound(Visible_Fields)
    Call mo_CheckView.ColumnHeaders.Add(, , GetFieldCaption(Visible_Fields(ll_Index)), Visible_Fields_Width(ll_Index))
  Next

#If CompDebugCV Then
  Call Trace.WriteTraceProc(False, "ArmCheckList:InitListColumns")
#End If
End Function

