#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.16.1
 Author:         Kanashius

 Script Function:
	Make debugging easier by just calling _toString at any variable.

#ce ----------------------------------------------------------------------------
#include-once

; #FUNCTION# =======================================================================================
; Name ..........: _toString
; Description ...: Writes the content of a variable as String to the console
; Syntax ........: _ToStringC($data, $bInformative = True, $sPrefixSep = @TAB, $sSpaceOuter = @crlf, $sSpaceInner = @crlf, $iDepth = 0)
; Parameters ....: $data                  - The variable to be converted.
;                  $bInformative          - The level of detail. When True, the type of all variables is returned and not only the content
;                  $sPrefixSep            - The prefix value used for indentation
;                  $sSpaceOuter           - The space between levels of dimensions (Array) or at the beginning of a Map/DllStruct
;                  $sSpaceInner           - The space between items of an Array/Map/DllStruct
;                  $iDepth                - INTERNAL: The depth level of the call. Used in recursive calls to indent items
; Return values .: String
; Author ........: Kanashius
; ==================================================================================================
Func _ToStringC(ByRef $data, $bInformative = True, $sPrefixSep = @TAB, $sSpaceOuter = @crlf, $sSpaceInner = @crlf)
	ConsoleWrite(_ToString($data, $bInformative, $sPrefixSep, $sSpaceOuter, $sSpaceInner)&@crlf)
EndFunc

; #FUNCTION# =======================================================================================
; Name ..........: _toString
; Description ...: Returns the content of a variable as String
; Syntax ........: _toString($data, $bInformative = True, $sPrefixSep = @TAB, $sSpaceOuter = @crlf, $sSpaceInner = @crlf, $iDepth = 0)
; Parameters ....: $data                  - The variable to be converted.
;                  $bInformative          - The level of detail. When True, the type of all variables is returned and not only the content
;                  $sPrefixSep            - The prefix value used for indentation
;                  $sSpaceOuter           - The space between levels of dimensions (Array) or at the beginning of a Map/DllStruct
;                  $sSpaceInner           - The space between items of an Array/Map/DllStruct
;                  $iDepth                - INTERNAL: The depth level of the call. Used in recursive calls to indent items
; Return values .: String
; Author ........: Kanashius
; ==================================================================================================
Func _ToString(ByRef $data, $bInformative = True, $sPrefixSep = @TAB, $sSpaceOuter = @crlf, $sSpaceInner = @crlf, $iDepth = 0)
	Local $sPrefix = ""
	For $i=0 to $iDepth-1
		$sPrefix &= $sPrefixSep
	Next
	If IsArray($data) Then
		Local $bPrefix = False
		If StringInStr($sSpaceOuter, @crlf) or StringInStr($sSpaceInner, @crlf) Then
			$bPrefix = True
		Else
			$sPrefixSep = ""
		EndIf
		Local $iDimensions = UBound($data, 0)
		Local $sDim = ""
		For $i = 1 to $iDimensions Step 1
			$sDim &= "["&UBound($data, $i)&"]"
		Next
		Local $sOut = $sPrefix & ($bInformative ? "Array"&$sDim&" [" : "[") & $sSpaceOuter
		For $i=0 To UBound($data, 1)-1 Step 1
			If $iDimensions<2 Then
				$sOut &= _toString($data[$i], $bInformative, $sPrefixSep, $sSpaceOuter, $sSpaceInner, $iDepth+1) & (($i<>UBound($data, 1)-1)?"," & $sSpaceInner:$sSpaceOuter)
			Else
				$sOut &= ($bPrefix?$sPrefix & $sPrefixSep:"") & "[" & $sSpaceOuter
				For $j=0 To UBound($data, 2)-1 Step 1
					If $iDimensions<3 Then
						$sOut &= _toString($data[$i][$j], $bInformative, $sPrefixSep, $sSpaceOuter, $sSpaceInner, $iDepth+2) & (($j<>UBound($data, 2)-1)?"," & $sSpaceInner:$sSpaceOuter)
					Else
						$sOut &= ($bPrefix?$sPrefix & $sPrefixSep & $sPrefixSep:"") & "[" & $sSpaceOuter
						For $k=0 To UBound($data, 3)-1 Step 1
							$sOut &= _toString($data[$i][$j][$k], $bInformative, $sPrefixSep, $sSpaceOuter, $sSpaceInner, $iDepth+3) & (($k<>UBound($data, 3)-1)?"," & $sSpaceInner:$sSpaceOuter)
						Next
						$sOut &= ($bPrefix?$sPrefix & $sPrefixSep & $sPrefixSep:"") & "]" & (($j<>UBound($data, 2)-1)?"," & $sSpaceInner:"") & $sSpaceOuter
					EndIf
				Next
				$sOut &= ($bPrefix?$sPrefix & $sPrefixSep:"") & "]" & (($i<>UBound($data, 1)-1)?"," & $sSpaceInner:$sSpaceOuter)
			EndIf
		Next
		$sOut &= ($bPrefix?$sPrefix:"") & "]"
		return $sOut
	ElseIf IsBinary($data) Then
		return $sPrefix & ($bInformative ? 'binary "'&String($data)&'"' : String($data))
	ElseIf IsBool($data) Then
		return $sPrefix & ($bInformative ? 'bool "'&StringLower(String($data))&'"' : StringLower(String($data)))
	ElseIf IsDllStruct($data) Then
		Local $bPrefix = StringInStr($sSpaceInner, @crlf)
		Local $sOut = $sPrefix & ($bInformative ? "DllStruct[b"&DllStructGetSize($data)&"]{" : "{") & $sSpaceOuter
		Local $iCount = 1
		While True
			Local $oTmp = DllStructGetData($data, $iCount)
			If @error Then ExitLoop
			$sOut &= _toString($oTmp, $bInformative, $sPrefixSep, $sSpaceOuter, $sSpaceInner, $iDepth+1)
			$iCount += 1
			$sOut &=  "," & $sSpaceInner
		WEnd
		$sOut &= ($bPrefix?$sPrefix:"") & "}"
		return $sOut
	ElseIf IsFunc($data) Then
		return $sPrefix & ($bInformative ? 'function "'&FuncName($data)&'"' : FuncName($data))
	ElseIf IsFloat($data) Then
		return $sPrefix &  ($bInformative ? 'float "'&String($data)&'"' : String($data))
	ElseIf IsHWnd($data) Then
		return $sPrefix & ($bInformative ? 'hwnd "'&String($data)&'"' : String($data))
	ElseIf IsInt($data) Then
		return $sPrefix &  ($bInformative ? 'int "'&String($data)&'"' : String($data))
	ElseIf IsKeyword($data) Then
		If $data=Default Then
			return $sPrefix & ($bInformative ? 'keyword "Default"' : "default")
		ElseIf $data=Null Then
			return $sPrefix & ($bInformative ? 'keyword "Null"' : "null")
		EndIf
	ElseIf IsMap($data) Then
		Local $sOut = $sPrefix & ($bInformative ? "Map["&UBound($data)&"] {" : "{") & $sSpaceOuter
		For $key in MapKeys($data)
			$sOut &= _toString($key, $bInformative, $sPrefixSep, $sSpaceOuter, $sSpaceInner, $iDepth+1) & ": " & $sSpaceOuter & _toString($data[$key], $bInformative, $sPrefixSep, $sSpaceOuter, $sSpaceInner, $iDepth+2)
			$sOut &=  "," & $sSpaceInner
		Next
		$sOut &= $sPrefix & "}"
		return $sOut
	ElseIf IsNumber($data) Then
		return $sPrefix &  ($bInformative ? 'number "'&String($data)&'"' : String($data))
	ElseIf IsObj($data) Then
		If ObjName($data, 1) = "Dictionary" Then
			__ToString_HasErrorOccurred(False)
			Local $oErrHandler = ObjEvent("AutoIt.Error", "__ToString_ErrFunc")
			Local $iCount = $data.count, $arKeys = $data.keys(), $test = $data.item("")
			If Not __ToString_HasErrorOccurred() Then
				Local $sOut =  $sPrefix & ($bInformative ? 'Object "'&ObjName($data, 1)&""" Description: """&ObjName($data, 2)&'" ' : ObjName($data, 1)) & "["&$iCount&"]" & "{" &$sSpaceOuter
				For $key in $arKeys
					Local $item = $data.item($key)
					$sOut &= _toString($key, $bInformative, $sPrefixSep, $sSpaceOuter, $sSpaceInner, $iDepth+1) & ": " & $sSpaceOuter & _toString($item, $bInformative, $sPrefixSep, $sSpaceOuter, $sSpaceInner, $iDepth+2)
					$sOut &=  "," & $sSpaceInner
				Next
				$sOut &= $sPrefix & "}"
				return $sOut
			EndIf
		EndIf
		return $sPrefix & ($bInformative ? 'Object "'&ObjName($data, 1)&""" Description: """&ObjName($data, 2)&'"' : ObjName($data, 1))
	ElseIf IsPtr($data) Then
		return $sPrefix & ($bInformative ? 'pointer "'&String($data)&'"' : String($data))
	ElseIf IsString($data) Then
		return $sPrefix & ($bInformative ? 'string "'&$data&'"' : '"'&$data&'"')
	Else
		return $sPrefix & ($bInformative ? 'unsupported ('&VarGetType($data)&') "'&String($data)&'"' : String($data))
	EndIf
EndFunc

; #FUNCTION# =======================================================================================
; Name ..........: __ToString_ErrFunc
; Description ...: INTERNAL AutoIt.Error catch method to allow for checking if an object can be
;                  iterated, without causing an error.
; Syntax ........: __ToString_ErrFunc($oError)
; Parameters ....: $oError                - The AutoIt.Error object
; Author ........: Kanashius
; ==================================================================================================
Func __ToString_ErrFunc($oError)
	__ToString_HasErrorOccurred(True)
EndFunc

; #FUNCTION# =======================================================================================
; Name ..........: __ToString_HasErrorOccurred
; Description ...: INTERNAL allows to check, if an error occurred while checking if an object can be
;                  iterated, without causing an error.
; Syntax ........: __ToString_HasErrorOccurred($bError = Default)
; Parameters ....: $bError                - Allows the __ToString_ErrFunc method to set the error
; Author ........: Kanashius
; ==================================================================================================
Func __ToString_HasErrorOccurred($bError = Default)
	Local static $bCurrentError = False
	If $bError<>Default Then
		$bCurrentError = $bError
	EndIf
	return $bCurrentError
EndFunc