content: REM If you import this, you also need to import Types and StringUtils
  REM
  REM Functions in this file:
  REM     Dbg
  REM     AnyToString
  REM     tostr
  REM     PrintAny
  REM     PrintAA
  REM     PrintList
  REM     PrintAnyAA
  REM     PrintAnyList
  REM     
  
  '******************************************************
  'Print an object as a string for debugging. If it is 
  'very long print the first 500 chars.
  '******************************************************
  Sub Dbg(pre As Dynamic, o=invalid As Dynamic)
      p = AnyToString(pre)
      if p = invalid p = ""
      if o = invalid o = ""
      s = AnyToString(o)
      if s = invalid s = "???: " + type(o)
      if Len(s) > 4000
          s = Left(s, 4000)
      endif
      print p + s
  End Sub
  
  
  '******************************************************
  'Try to convert anything to a string. Only works on simple items.
  '
  'Test with this script...
  '
  '    s$ = "yo1"
  '    ss = "yo2"
  '    i% = 111
  '    ii = 222
  '    f! = 333.333
  '    ff = 444.444
  '    d# = 555.555
  '    dd = 555.555
  '    bb = true
  '
  '    so = CreateObject("roString")
  '    so.SetString("strobj")
  '    io = CreateObject("roInt")
  '    io.SetInt(666)
  '    tm = CreateObject("roTimespan")
  '
  '    Dbg("", s$ ) 'call the Dbg() function which calls AnyToString()
  '    Dbg("", ss )
  '    Dbg("", "yo3")
  '    Dbg("", i% )
  '    Dbg("", ii )
  '    Dbg("", 2222 )
  '    Dbg("", f! )
  '    Dbg("", ff )
  '    Dbg("", 3333.3333 )
  '    Dbg("", d# )
  '    Dbg("", dd )
  '    Dbg("", so )
  '    Dbg("", io )
  '    Dbg("", bb )
  '    Dbg("", true )
  '    Dbg("", tm )
  '
  'try to convert an object to a string. return invalid if can't
  '******************************************************
  Function AnyToString(any As Dynamic) As dynamic
      if any = invalid return "invalid"
      if isstr(any) return any
      if isint(any) return itostr(any)
      if isbool(any)
          if any = true return "true"
          return "false"
      endif
      if isfloat(any) return Str(any)
      if type(any) = "roTimespan" return itostr(any.TotalMilliseconds()) + "ms"
      if type(any) = "roDateTime" return DateTimeToString(any)
      return invalid
  End Function
  
  
  '******************************************************
  'Convert anything to a string
  '
  'Always returns a string
  '******************************************************
  Function tostr(any)
      ret = AnyToString(any)
      if ret = invalid ret = type(any)
      if ret = invalid ret = "unknown" 'failsafe
      return ret
  End Function
  
  
  '******************************************************
  'Print anything
  '******************************************************
  Sub PrintAny(depth As Integer, prefix As String, any As Dynamic)
      if tooDeep(depth) then return
      prefix = string(depth*2," ") + prefix
      depth = depth + 1
      str = AnyToString(any)
      if str <> invalid
          print prefix + str
          return
      endif
      if type(any) = "roAssociativeArray"
          print prefix + "(assocarr)..."
          PrintAnyAA(depth, any)
          return
      endif
      if islist(any) = true
          print prefix + "(list of " + itostr(any.Count()) + ")..."
          PrintAnyList(depth, any)
          return
      endif
  
      print prefix + "?" + type(any) + "?"
  End Sub
  
  
  '******************************************************
  'Walk an AA and print it
  '******************************************************
  Sub PrintAA(aa as Object)
      print "---- AA ----"
      if aa = invalid
          print "invalid"
          return
      else
          cnt = 0
          for each e in aa
              x = aa[e]
              PrintAny(0, e + ": ", aa[e])
              cnt = cnt + 1
          next
          if cnt = 0
              PrintAny(0, "Nothing from for each. Looks like :", aa)
          endif
      endif
      print "------------"
  End Sub
  
  
  '******************************************************
  'Walk a list and print it
  '******************************************************
  Sub PrintList(list as Object)
      print "---- list ----"
      PrintAnyList(0, list)
      print "--------------"
  End Sub
  
  Sub tooDeep(depth As Integer) As Boolean
      hitLimit = (depth >= 10)
      if hitLimit then  print "**** TOO DEEP "; depth
      return hitLimit
  End Sub
  
  '******************************************************
  'Print an associativearray
  '******************************************************
  Sub PrintAnyAA(depth As Integer, aa as Object)
      if tooDeep(depth) then return
      for each e in aa
          x = aa[e]
          PrintAny(depth, e + ": ", aa[e])
      next
  End Sub
  
  
  '******************************************************
  'Print a list with indent depth
  '******************************************************
  Sub PrintAnyList(depth As Integer, list as Object)
      if tooDeep(depth) then return
      i = 0
      for each e in list
          PrintAny(depth, "List(" + itostr(i) + ")= ", e)
          i = i + 1
      next
  End Sub
  
  '******************************************************
  'Converts a roDateTime to a string
  '******************************************************
  Function DateTimeToString(o)
      s = ""
      s = s + ZeroPad(o.getMonth()        , 2) + "/"
      s = s + ZeroPad(o.getDayOfMonth()   , 2) + "/" 
      s = s + ZeroPad(o.getYear()         , 2) + " " 
      s = s + ZeroPad(o.getHours()        , 2) + ":" 
      s = s + ZeroPad(o.getMinutes()      , 2) + ":" 
      s = s + ZeroPad(o.getSeconds()      , 2) + "." 
      s = s + ZeroPad(o.getMilliseconds() , 3)
      return s
  End Function
  
  Function ZeroPad(i, width)
      ' This needs to be trimmed because str() on a number includes
      ' a leading space for a possible negative sign
  
      ' This little but may look a little strange. It's
      ' because  istr = str(i).Trim() leaks memory (or used to).
      s1 = CreateObject("roString")
      s1.SetString(str(i))
      istr = s1.Trim()
      
      istr_len = len(istr)
      if (istr_len >= width) then
          return istr
      end if
  
      return (string(width-istr_len,"0") + istr)
  End Function
  