' sys_debug.inc
' These routines are for development debugging purposes only and can
' be excluded from the DLL by not defining the %CHEETAH_DEVELOPER_DEBUG equate

'//
'//  DEBUG - Display the contents of the Memo garbage chain.
'//                                                         
'Function xdbShowGarbageChain( ByVal xdb As CHEETAH4_TYPE Ptr ) Export As Long
'
'   Local pDBF   As DBF_TYPE Ptr
'   Local pChain As DBF_GARBAGEMEMO_TYPE Ptr
'   Local y      As Long  
'   Local st     As String
'   
'   pDBF = @xdb.reserved
'
'   pChain = VarPtr(@pDBF.DBH_MEMO.GarbageChain(1))
'   For y = 1 To %MAX_GARBAGECHAIN
'      If @pChain.NumGarbageBlocks > 0 Then
'         st = st & "Pos:" & Str$(y) & _
'                   "  StartBlock:" & Str$(@pChain.BlockNumber) & _
'                   "  NumBlocks:" & Str$(@pChain.NumGarbageBlocks) & $CrLf
'      End If   
'      Incr pChain
'   Next  
'   
'   MsgBox st,,"Garbage Chain"
'   
'End Function


'//
'//  Dump an index and Tags to a disk file
'//
Function ctx_DumpIndex_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long

   Local pBTX        As BTX_TYPE Ptr 
   Local LookupNode  As INDEX_LOOKUP_NODE_TYPE
   Local RegularNode As INDEX_REGULAR_NODE_TYPE
   Local pTAG        As INDEX_TAG_TYPE_MEMORY Ptr
   Local hFile       As Long
   Local errcode     As Long
   Local sFilename   As String   
   Local KeyString   As String
   Local PreviousKey As String
   Local RecNum      As Long
   Local NextNode    As Long
   Local FirstNode   As Long
   Local x           As Long
   Local y           As Long   
   Local SequenceFlag As Long
   Local KeyCount    As Long 
   Local nMaxKeySize As Long
   Local sDisplayKey As String
   Local nKeyNum     As Long
   Local PreviousLookupKey As String
   Local LookupSequenceFlag As Long
   
   sFilename = Peek$( @xdb.nData, @xdb.nLen )
   
   pBTX  = @xdb.reserved
   
   
   hFile = FreeFile
   Open sFilename For Append As #hFile
   
   Print #hFile, ""
   Print #hFile, "----- INDEX DUMP" & Str$(pBTX) & " -----"
   Print #hFile, "  pNextBTX             =" & Str$(@pBTX.pNextBTX)
   Print #hFile, "  pFirstTAG            =" & Str$(@pBTX.pFirstTAG)
   Print #hFile, "  hFile                =" & Str$(@pBTX.hFile)
   Print #hFile, "  pDBF                 =" & Str$(@pBTX.pDBF)
   Print #hFile, "  --- Header ---"
   Print #hFile, "  idBytes    = " & @pBTX.BTH.idBytes
   Print #hFile, "  Version    ="  & Str$(@pBTX.BTH.Version)
   Print #hFile, "  FreeList   ="  & Str$(@pBTX.BTH.FreeList)        
   Print #hFile, "  NumTags    ="  & Str$(@pBTX.BTH.NumTags)        
   Print #hFile, "  TotalNodes ="  & Str$(@pBTX.BTH.TotalNodes)       

   Print #hFile, "  pTagDisk(mem) =";
   For x = 1 To 5  '%INDEX_MAX_TAG_FIELDS
      Print #hFile, "["; Format$(VarPtr(@pBTX.BTH.Tags(x))); " "; @pBTX.BTH.Tags(x).TagName; "] ";
   Next            
   Print #hFile, " ... (to %INDEX_MAX_TAG_FIELDS)"
   
   Print #hFile, "  --- Tags ---"
   pTAG = @pBTX.pFirstTAG
   Do Until pTAG = 0
      Print #hFile, "  pTAG           =" & Str$(pTAG)
      Print #hFile, "  pNextTAG       =" & Str$(@pTAG.pNextTAG)
      Print #hFile, "  pTagDisk       =" & Str$(@pTAG.pTagDisk)
      Print #hFile, "  LookupNodeNum  =" & Str$(@pTAG.LookupNodeNum)
      Print #hFile, "  RegularNodeNum =" & Str$(@pTAG.RegularNodeNum)
      Print #hFile, "  RegularNodePos =" & Str$(@pTAG.RegularNodePos)
      Print #hFile, "  TagName        = " & @pTAG.@pTagDisk.TagName
      Print #hFile, "  FirstLookupNode=" & Str$(@pTAG.@pTagDisk.FirstLookupNode)
      Print #hFile, "  KeySize        =" & Str$(@pTAG.@pTagDisk.KeySize)
      Print #hFile, "  MaxKeys        =" & Str$(@pTAG.@pTagDisk.MaxKeys)
      Print #hFile, "  HalfNode       =" & Str$(@pTAG.@pTagDisk.HalfNode)
      Print #hFile, "  IndexFields    =";
      For x = 1 To %INDEX_MAX_TAG_FIELDS
         Print #hFile, Str$(@pTAG.@pTagDisk.Fields(x));
      Next

      nMaxKeySize = IIf&( @xdb.nData4Byte <> 0, @xdb.nData4Byte, @pTAG.@pTagDisk.KeySize )
      sDisplayKey = Space$( nMaxKeySize )

      KeyCount  = 0
      FirstNode = 0   ' first RegularNode
      NextNode = @pTAG.@pTagDisk.FirstLookupNode
      Print #hFile, ""   
      PreviousLookupKey = ""
      Do Until NextNode = 0
         ctx_GetNode_Internal pBTX, NextNode, VarPtr(LookupNode)
         Print #hFile, "  *LOOKUPNODE SEQUENCE:  Node:" & Str$(NextNode) & "   NextNode:" & Str$(LookupNode.NextNode)
         For x = 1 To %INDEX_MAX_LOOKUP_KEYS
            If LookupNode.Node(x) = 0 Then Iterate For
            If FirstNode = 0 Then FirstNode = LookupNode.Node(x)
            Print #hFile, "    Lookup" & Format$(x) & "    Key: " & LookupNode.Key(x) & "  Node:" & Str$(LookupNode.Node(x))
            
            If PreviousLookupKey = "" Then
               PreviousLookupKey = LookupNode.Key(x)
            Else
               If LookupNode.Key(x) < PreviousLookupKey Then
                  Print #hFile, "   **** OUT OF SEQUENCE ****"
                  LookupSequenceFlag = %TRUE
               End If
               PreviousLookupKey = LookupNode.Key(x)
            End If   
         Next
         NextNode = LookupNode.NextNode
      Loop
            

      Print #hFile, ""            
      Print #hFile, "   *NODE SEQUENCE:"            
      Print #hFile, ""            
      
      nKeyNum     = 0
      PreviousKey = ""
      
      NextNode = FirstNode
      Do Until NextNode = 0
         ctx_GetNode_Internal pBTX, NextNode, VarPtr(RegularNode)
         
         Print #hFile, "    Node:" & Str$(NextNode) & "   PrevNode:" & Str$(RegularNode.PrevNode) & "  NextNode:" & Str$(RegularNode.NextNode) & "  NumKeys:" & Str$(RegularNode.NumKeys)
         For y = 1 To RegularNode.NumKeys
             KeyString = Mid$(RegularNode.Buffer, ((y-1) * (@pTAG.@pTagDisk.KeySize+4)) + 1, @pTAG.@pTagDisk.KeySize)
             RecNum    = Peek( Long, VarPtr(RegularNode.Buffer) + _
                                     ( (y-1) * ( @pTAG.@pTagDisk.KeySize + 4 ) ) + @pTAG.@pTagDisk.KeySize ) 

             LSet sDisplayKey = KeyString
             
             Incr nKeyNum
             Print #hFile, Str$(nKeyNum) & "    Pos:" & Str$(y) & "  Key: " & sDisplayKey & "   RecNum:" & Str$(RecNum)
             
             Incr KeyCount
             
             If PreviousKey = "" Then
                PreviousKey = KeyString
             Else
                If KeyString < PreviousKey Then
                   Print #hFile, "   **** OUT OF SEQUENCE ****"
                   SequenceFlag = %TRUE
                End If
                PreviousKey = KeyString
             End If   
         Next 
         Print #hFile, ""            
            
         NextNode = RegularNode.NextNode
      Loop
         
      Print #hFile, ""
      Print #hFile, "   Keys read:" & Str$(KeyCount)
      Print #hFile, "--------------------"
      pTAG = @pTAG.pNextTAG 
   Loop               
   
   Print #hFile, "--------------------"

   Close #hFile              
   
   If SequenceFlag Then
      MsgBox "REGULAR NODE OUT OF SEQUENCE OCCURRED"
   End If   
   If LookupSequenceFlag Then
      MsgBox "LOOKUP NODE OUT OF SEQUENCE OCCURRED"
   End If   
   
   
   MsgBox "   Keys read:" & Str$(KeyCount)
   
ExitOut:
   Function = errcode 


End Function

