VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "InfoWordDatabase"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit

Public source_ As InfoDatabase

Public Function Init(iDatabase As InfoDatabase)
  Set source_ = iDatabase
End Function

Public Function Contains(gid&) As Boolean
  Contains = source_.Contains(gid)
End Function

Public Function SyncLink(hLink As Word.Hyperlink, iDoc As InfoDocument) As IteratorLinkCached
  Dim iLink As ItemHyperlink: Set iLink = ParseHyperlink(hLink)
  Dim itLink As IteratorLinkCached: Set itLink = source_.LawLinksCached(iDoc.gid_)
  If itLink Is Nothing Then _
    Call Err.Raise(ERR_INVALID_LINK_NUMBER)
    
  Dim linkNo&: linkNo = iDoc.CountLinksBefore(hLink.Range.End)
  If Not itLink.Increment(linkNo - 1) Then _
    Call Err.Raise(ERR_SYNC_DB)
  Call iLink.ValidateSync(itLink)
  Set SyncLink = itLink
End Function

Public Function LoadLinksFrom(target As InfoDocument)
  Dim linkItems As Collection: Set linkItems = ExtractLinksData(target)
  If linkItems.Count = 0 Then _
    Exit Function
  
  Dim linksData() As String
  ReDim linksData(1 To linkItems.Count, LinkTransferStruct.[_First] To LinkTransferStruct.[_Last])
  Dim nItem&
  Dim anItem As ItemLink
  For nItem = 1 To linkItems.Count
    Set anItem = linkItems(nItem)
    linksData(nItem, S_TL_DESTINATION_ID) = CStr(anItem.destID_)
    linksData(nItem, S_TL_DESTINATION_SUB) = anItem.destSub_
    linksData(nItem, S_TL_SOURCE_SUB) = anItem.sourceSub_
  Next nItem
  
  Call source_.SetLinksFor(target.gid_, linksData)
End Function

Public Function ExpressLinks(target As InfoDocument)
  Dim itLink As IteratorLinkCached: Set itLink = source_.LawLinksCached(target.gid_)
  Dim aLink As Word.Hyperlink
  For Each aLink In target.doc_.Hyperlinks
    If Not IsHyperlinkValid(aLink) Then _
       GoTo NEXT_LNK
    
    If Not itLink.IsProcessed Then
      If itLink.LType = T_LINK_DEFAULT Then _
        itLink.LType = T_LINK_DEFINITION
      If IsGarantComment(aLink.Range.Paragraphs(1).Range) Then _
        itLink.Status = T_LINKS_IGNORE
    End If
    
    Call itLink.Increment
NEXT_LNK:
    Call CSE_ProgressBar.IncrementA
  Next aLink
End Function

Public Function ExpressDocuments(theType As TLawType, target As Word.Range) As Scripting.Dictionary
  Dim newDocs As New Scripting.Dictionary
  
  Dim props As New ItemLaw
  props.type_ = theType
  props.status_ = T_LAWS_OUTER
  
  Dim newDoc As Word.Document
  Dim aPar As Word.Paragraph
  Dim iLink As ItemHyperlink
  Dim theLink As Word.Hyperlink
  For Each aPar In target.Paragraphs
    For Each theLink In aPar.Range.Hyperlinks
      Set iLink = ParseHyperlink(theLink)
      If iLink Is Nothing Then _
        GoTo NEXT_LINK
        
      props.gid_ = iLink.DocumentID
      props.title_ = ExtractTitleFromMention(aPar.Range)
      props.isDummy_ = True
      
      If Not source_.Contains(props.gid_) Then
        props.fileName_ = source_.GenerateFileName(props.title_)
        Call AddDummyDocument(props, source_.docsLocation_, iLink.LinkSystem)
        Call source_.SetItem(props)
        Call newDocs.Add(iLink.DocumentID, 0)
      End If
      Exit For
NEXT_LINK:
    Next theLink
    Call CSE_ProgressBar.IncrementA
  Next aPar
  
  Set ExpressDocuments = newDocs
End Function

Public Function AddLinkAfter(iLink As ItemLink, nWhereIndex&) As Boolean
  AddLinkAfter = source_.AddLinkAfter(iLink.sourceID_, nWhereIndex, iLink.destID_, iLink.destSub_, iLink.sourceSub_, iLink.type_)
End Function

Public Function OpenHyperlink(target As Word.Hyperlink) As Boolean
  OpenHyperlink = False
  
  Dim iLink As ItemHyperlink: Set iLink = ParseHyperlink(target)
  If Not source_.Contains(iLink.DocumentID) Then _
    Call Err.Raise(EM_LINK_NO_FILE, iLink.ToAddress)
    
  Dim docIter As IteratorLaw: Set docIter = source_.Data(iLink.DocumentID)
  Dim wordWrap As New API_WordWrapper
  If wordWrap.OpenDocument(source_.docsLocation_ & "\" & docIter.FileName, bReadOnly:=True, bTrackMRU:=True) Is Nothing Then _
    Exit Function
 
  Dim sBookmark$: sBookmark = iLink.BookmarkName
  With wordWrap.Document
    If .Bookmarks.Exists(sBookmark) Then
      Call .ActiveWindow.ScrollIntoView(.Bookmarks(sBookmark).Range)
      Call .Bookmarks(sBookmark).Range.Select
    ElseIf sBookmark <> "sub_0" Then
      Call Err.Raise(EM_BOOKMARK_INVALID, sBookmark)
    Else
      Call .ActiveWindow.ScrollIntoView(.Range(1, 1))
    End If
  End With
  
  OpenHyperlink = True
End Function

' ==========
Private Function ExtractLinksData(target As InfoDocument) As Collection
  Dim theLinks As New Collection
  Dim iLink As ItemHyperlink
  Dim docHLink As Word.Hyperlink
  For Each docHLink In target.doc_.Hyperlinks
    Set iLink = ParseHyperlink(docHLink)
    If iLink Is Nothing Then _
      GoTo NEXT_LINK
    
    Dim subFrom$
    If docHLink.Range.Bookmarks.Count = 0 Then
      subFrom = CreateBookmarkFor(docHLink.Range)
    Else
      subFrom = docHLink.Range.Bookmarks(1).Name
    End If
    
    Dim anItem As ItemLink: Set anItem = New ItemLink
    anItem.destID_ = iLink.DocumentID
    anItem.destSub_ = iLink.BookmarkName
    anItem.sourceSub_ = subFrom
    
    Call theLinks.Add(anItem)
    
NEXT_LINK:
    Call CSE_ProgressBar.IncrementA
  Next docHLink
  
  Set ExtractLinksData = theLinks
End Function

Private Function IsGarantComment(target As Word.Range) As Boolean
  IsGarantComment = target.Style = "Êîììåíòàðèé"
End Function

Private Function ExtractTitleFromMention(ByRef target As Word.Range) As String
  Call target.MoveStartWhile("[0123456789. ]")
  Dim theText$: theText = target.Text
  
  Dim endPos&: endPos = Len(theText)
  Dim pos1&: pos1 = InStr(1, UCase(theText), "ÐÀÇÄÅË", vbTextCompare)
  If pos1 <> 0 And endPos > pos1 Then _
    endPos = pos1 - 3
  
  Dim pos2&: pos2 = InStr(1, UCase(theText), "ÏÓÍÊÒ", vbTextCompare)
  If pos2 <> 0 And endPos > pos2 Then _
    endPos = pos2 - 3
  
  Dim pos3&: pos3 = InStr(1, UCase(theText), "ÀÁÇÀÖ", vbTextCompare)
  If pos3 <> 0 And endPos > pos3 Then _
    endPos = pos3 - 3
  
  ExtractTitleFromMention = SubstituteWhitespace(Left(theText, endPos))
End Function
