Attribute VB_Name = "DataAccess"
' Функции доступа к данным
Option Explicit

Public Function GetDBPath() As String
  GetDBPath = ThisWorkbook.Names(VIEW_CELL_DBPATH).RefersToRange.Text
End Function

Public Function AccessDatabase() As API_XLWrapper
  Dim inputPath$: inputPath = GetDBPath
  
  Dim result As New API_XLWrapper
  Call result.SetApplication(ThisWorkbook.Application)
  If result.OpenDocument(inputPath, bReadOnly:=True) Is Nothing Then
    Call UserInteraction.ShowMessage(EM_DATABASE_NOT_FOUND)
  Else
    Set AccessDatabase = result
  End If
End Function

Public Function AccessLocal() As InfoDatabase
  Set AccessLocal = New InfoDatabase
  Call AccessLocal.Init(ThisWorkbook, ThisWorkbook.Names(VIEW_CELL_LAWS).RefersToRange)
End Function

Public Function GetVisibleLaws() As Scripting.Dictionary
  Set GetVisibleLaws = New Scripting.Dictionary
  Dim docsSht As Excel.Worksheet: Set docsSht = GetActiveDocsSheet
  Dim idsRange As Excel.Range: Set idsRange = docsSht.Range("A2:A" & docsSht.UsedRange.Rows.Count).SpecialCells(xlCellTypeVisible)
  Dim theDB As InfoDatabase: Set theDB = AccessLocal
  Dim aCell As Excel.Range
  For Each aCell In idsRange
    Dim gid&: gid = VBA.CLng(aCell.Text)
    If theDB.Contains(gid) Then _
      Call GetVisibleLaws.Add(gid, 0)
  Next aCell
End Function

Public Function GetSelectedLaws() As Scripting.Dictionary
  Dim sel As Excel.Range: Set sel = ThisWorkbook.Application.Selection
  If sel.Parent.Parent.Name <> ThisWorkbook.Name Then
    Call UserInteraction.ShowMessage(EM_INVALID_SELECTION)
    Exit Function
  End If
  
  Dim theDB As InfoDatabase: Set theDB = AccessLocal
  Set GetSelectedLaws = New Scripting.Dictionary
  Dim aCell As Excel.Range
  For Each aCell In sel
    Dim sText$: sText = aCell
    If IsNumeric(sText) Then
      Dim gid&: gid = CLng(sText)
      If theDB.Contains(gid) Then _
        Call GetSelectedLaws.Add(gid, 0)
    End If
  Next aCell
End Function

Public Function VisibleLinkRows() As Collection
  Dim linksSht As Excel.Worksheet: Set linksSht = ThisWorkbook.Sheets(SHT_LINKS)
  Dim lnksRange As Excel.Range: Set lnksRange = linksSht.Range("A2:A" & linksSht.UsedRange.Rows.Count).SpecialCells(xlCellTypeVisible)
  
  Set VisibleLinkRows = New Collection
  Dim aCell As Excel.Range
  For Each aCell In lnksRange
    Call VisibleLinkRows.Add(CStr(aCell.Row), CStr(aCell.Row))
  Next aCell
End Function

' template linkFilter
' !requires function CheckLink(IteratorLinkAll) -> Boolean
Public Function CreateGraph(Optional iFilter As Object = Nothing) As CDS_Graph
  Set CreateGraph = New CDS_Graph
  Dim Data As InfoDatabase: Set Data = AccessLocal
  Dim docIter As IteratorLaw: Set docIter = Data.Laws
  Do While Not docIter.IsDone
    Call CreateGraph.AddNode(CStr(docIter.ID))
    Call docIter.Increment
  Loop
  
  Dim iLink As IteratorLinkAll: Set iLink = Data.Links
  Do While Not iLink.IsDone
    If Not iFilter Is Nothing Then _
      If Not iFilter.CheckLink(iLink) Then _
        GoTo NEXT_LINK
    
    Call CreateGraph.AddEdge(iLink.SourceID, iLink.DestinationID)
    
NEXT_LINK:
    Call iLink.Increment
  Loop
End Function

Public Function DoIncludeTBALinks() As Boolean
   DoIncludeTBALinks = ThisWorkbook.Names(PARAM_INCLUDE_TBA).RefersToRange = "ДА"
End Function

' =======
Private Function GetActiveDocsSheet() As Excel.Worksheet
  If Excel.Application.ActiveWorkbook.Name <> ThisWorkbook.Name Then
    Set GetActiveDocsSheet = ThisWorkbook.Sheets(SHT_DOCS)
    Exit Function
  End If
  
  Dim activeName$: activeName = Application.ActiveSheet.Name
  If activeName = SHT_DOCS Or activeName = SHT_IGNORE Or activeName = SHT_OUT_DOCS Then
    Set GetActiveDocsSheet = Application.ActiveSheet
  Else
    Set GetActiveDocsSheet = ThisWorkbook.Sheets(SHT_DOCS)
  End If
End Function
