#include-once
#include <GuiEdit.au3>
#include <FTPEx.au3>
#include <Array.au3>

;===============================================================================
; Function Name:	_getAllFTPFilesRekursiv($l_FTPSession, $sRemote = "", $sLocal = @TempDir, $iMaxDepth, $iDebug = 0, $idPrgKB = 0, $idLblKB = 0, $idLblKBPer = 0, $idPrgFile = 0, $idLblFile = 0, $idLblFilePer = 0, $idLblColapsed = 0, $idLblKBperSec = 0, $idLblLog = 0)
; Description::		lädt einen bestimmten Ordner inkl. aller Unterverzeichnisse herunter
; Parameter(s):   	$l_FTPSession	das von _FTP_Connect zurückgegebene Handle		Angabe ist Pflicht
;					$sRemote		der FTP-Ordner der heruntergeladen werden soll	optionale Angabe Leer=Rootverzeichnis
;					$sLocal			der loakle Ordner in dem die Dateien			optionale Angabe Leer=@TempDir
;									gespeichert werden sollen, die Unter-
;									verzeichnisse werden angelegt
;									siehe dazu _createLocalDirIfNecessary
;					$iMaxDepth		maximale Rekursionstiefe
;										<1 = unendlich als Degault eingestellt	optionale Angabe
;					$iDebug	sollen Debuginfos in der Scitekosole angezeigt werden?	optionale Angabe
;									Default = 	0 = keine DebugInfos,
;									1 = Debubinfos anzeigen
;									2 = DebugInfos und ArrayDisplays
;						*** folgende opt. Parameter erleichtern die Sarstellung in einer GUI 	***
;						*** sie sind alle mit 0 vorbelegt, d.h. kein GUI-Control wird upgedatet ***
;					$idPrgKB		ControldID der Progressbar (Dateigrösse)		optionale Angabe
;					$idLblKB		" des Labels (anhand der Dateigrösse)			optionale Angabe
;					$idLblKBPer		" des Labels für Prozent (Dateigrösse)			optionale Angabe
;					$idPrgFile		ControldID der Progressbar (Dateianzahl)		optionale Angabe
;					$idLblFile		" des Labels (anhand der Dateianzahl)			optionale Angabe
;					$idLblFilePer	" des Labels für Prozent (Dateianzahl)			optionale Angabe
;					$idLblColapsed	" des Labes für benötigte Zeit					optionale Angabe
;					$idLblKBperSec	" des Labels für erreichte KB/sec				optionale Angabe
;					$idLblLog		" des Edits Logübersicht						optionale Angabe
; Autor(s):			AutoBert (www.autoit.de)
;					zur freien Benutzung in eigenen Skripten und auch zur freien Weitergabe unter der Vorgabe,
;					dass diese Funktionsbeschreibumg inkl. Autor nicht enfernt wird
;===============================================================================
Func _getAllFTPFilesRekursiv($l_FTPSession, $sRemote = "", $sLocal = @TempDir, $iMaxDepth = -1, $iDebug = 0, $idPrgKB = 0, $idLblKB = 0, $idLblKBPer = 0, $idPrgFile = 0, $idLblFile = 0, $idLblFilePer = 0, $idLblColapsed = 0, $idLblKBperSec = 0, $idLblLog = 0)
	Local $aResult[1][2]
	Local $errGet
	Local $s_LocalFile
	Local $hLog=0
	Local $iKBPer = 0, $iFilePer = 0, $iKB_Already = 0, $iStart, $iSec, $sMsg, $sLog
	ToolTip('Searching for files to download, please wait...') ;kann auskommentiert werden
	if $idLblLog<>0 Then $hLog=GUICtrlGetHandle($idLblLog)
	If $idLblColapsed <> 0 Or $idLblKBperSec <> 0 Then $iStart = TimerInit()
	_FTP_FileList_Rekursiv2D($l_FTPSession, $aResult, $sRemote, False, $iMaxDepth, $iDebug)
	If $iDebug = 2 Then _ArrayDisplay($aResult, 'Rückgabe _FTP_FileList_Rekursiv2D')
	ToolTip('Downloading, please wait...') ;kann auskommentiert werden
	For $i = 1 To $aResult[0][0]
		;		$s_LocalFile = $sLocal & "\" & StringTrimLeft($aResult[$i][0], 1)
		$s_LocalFile = $sLocal & "\" & $aResult[$i][0]
		$s_LocalFile = StringReplace($s_LocalFile, "/", "\")
		_createLocalDirIfNecessary($s_LocalFile)
		$sLog="Download: " & $i & "/" & $aResult[0][0] & " :" & $aResult[$i][0] & @TAB
		If $idLblFile <> 0 Then GUICtrlSetData($idLblFile, $aResult[$i][0] & @TAB & $i & "/" & $aResult[0][0])
		If _FTP_FileGet($l_FTPSession, $aResult[$i][0], $s_LocalFile) Then;,"_UpdateProgress") Then
			$errGet = @error
			If $hLog <> 0 Then $sLog &= "erfolgreich "
			If $i = 1 Then
				$iKB_Already = $aResult[1][1]
			Else
				$iKB_Already += $aResult[$i][1]
			EndIf
		Else
			If $hLog <> 0 Then $sLog &= "fehlgeschlagen "
			If _FTP_DirSetCurrent($l_FTPSession, $aResult[$i][0]) Then
				If $hLog <> 0 Then $sLog &= " da ein Mountpoint "
				$aResult[0][1] -= $aResult[$i][1] ;kein Fehler daher von Gesamtsumme abziehen
			EndIf
		EndIf
		$sLog &= $errGet
		_report($sLog, $hLog, $iDebug)
		If $idPrgFile <> 0 Or $idLblFilePer <> 0 Then ;Prozente anhand Dateianzahl errechnen und anzeigen
			$iFilePer = Int($i / $aResult[0][0] * 100)
			If $idPrgFile <> 0 Then GUICtrlSetData($idPrgFile, $iFilePer)
			If $idLblFilePer <> 0 Then GUICtrlSetData($idLblFilePer, $iFilePer & "%")
		EndIf
		If $idPrgKB <> 0 Or $idLblKBPer <> 0 Then ;Prozente anhand Grösse errechnen und anzeigen
			$iKBPer = Int($iKB_Already / $aResult[0][1] * 100)
			If $idPrgKB <> 0 Then GUICtrlSetData($idPrgKB, $iKBPer)
			If $idLblKBPer <> 0 Then GUICtrlSetData($idLblKBPer, $iKBPer & "%")
		EndIf
		If $idLblKB <> 0 Then GUICtrlSetData($idLblKB, $iKB_Already & @TAB & "/" & $aResult[0][1])
	Next
	If $idLblColapsed <> 0 Or $idLblKBperSec <> 0 Then
		$iSec = TimerDiff($iStart) / 1000
		If $idLblKBperSec <> 0 Then GUICtrlSetData($idLblKBperSec, Round($iKB_Already / 1024 / $iSec, 2) & " KB/sec")
		If $idLblColapsed <> 0 Then
			Local $iMin = Int($iSec / 60), $iHour
			If $iMin > 0 Then
				$iSec -= $iMin * 60
				$iHour = Int($iMin / 60)
				If $iHour > 0 Then
					$iMin -= $iHour * 60
					$sMsg = StringFormat("%02d:%02d Stunden", $iHour, $iMin, $iSec)
				Else
					$sMsg = StringFormat("%02d:%02d Minuten", $iMin, $iSec)
				EndIf
			Else
				If $iSec > 0 Then $sMsg = StringFormat("%02d Sekunden", $iSec)
			EndIf
			GUICtrlSetData($idLblColapsed, "benötigt: " & $sMsg)
		EndIf
	EndIf
	ToolTip('') ;kann auskommentiert werden
EndFunc   ;==>_getAllFTPFilesRekursiv


;===============================================================================
; Function Name:	_createLocalDirIfNecessary($s_LocalFile)
; Description::		prüft ob für eine Datei die lokale Verzeichnisstruktur besteht, falls nötig wird diese angelegt
; Parameter(s):		$s_LocalFile	Dateuname für den die Verzeichnisstruktur geprüft werden soll
; Autor(s):			AutoBert (www.autoit.de)
;					zur freien Benutzung in eigenen Skripten und auch zur freien Weitergabe unter der Vorgabe,
;					dass diese Funktionsbeschreibumg inkl. Autor nicht enfernt wird
;===============================================================================
Func _createLocalDirIfNecessary($s_LocalFile)
	Local $aLocalPath = StringSplit($s_LocalFile, "\") ;hier lokale Pfad erstellen falls notwendig
	Local $sLocalPath = ""
	For $j = 1 To $aLocalPath[0] - 1
		$sLocalPath &= $aLocalPath[$j] & "\"
		$sLocalPath=StringReplace($sLocalPath,"\\","\")
		If Not FileExists($sLocalPath) And Not StringInStr($aLocalPath[$j], ":") Then
			DirCreate($sLocalPath)
			_report($sLocalPath & ' angelegt '&@error,0,1)
		EndIf
	Next
EndFunc   ;==>_createLocalDirIfNecessary

;===============================================================================
; Function Name:  	_FTP_FileList_Rekursiv2D($l_FTPSession, $aResult, $sPath, $bFolders=False, $iMaxDepth=-1, $iDebug=0)
; Description::   	füllt ein Array mit Dateien (und Verzeichnissen wenn $bFolders true) des FTP-Pfades inkl. aller Unterverzeichnisse
; Parameter(s):   	$l_FTPSession	das von _FTP_Connect zurückgegebene Handle
;					$aResult   = das Array in dem die Ergebnisse eingefügt werden
;					$sPath     = Verzeichnispfad, der eingefügt werden soll
;					$bFolders    = True = auch Verzeichnisse einfügen, False = nur Dateien, Default = nur Dateien
;					$iMaxDepth		maximale Rekursionstiefe
;										<1 = unendlich als Degault eingestellt	optionale Angabe
;					$iDebug	sollen Debuginfos in der Scitekosole angezeigt werden?
;									Default = 	0 = keine DebugInfos,
;									1 = Debubinfos anzeigen
;									2 = DebugInfos und ArrayDisplays
; Autor(s):			AutoBert (www.autoit.de)
;					zur freien Benutzung in eigenen Skripten und auch zur freien Weitergabe unter der Vorgabe,
;					dass diese Funktionsbeschreibumg inkl. Autor nicht enfernt wird
;
;					Achtung benötugt bugfreie Version von FTPEx.au3 (3.3.6.1)
;===============================================================================
Func _FTP_FileList_Rekursiv2D($l_FTPSession, ByRef $aResult, $sPath, $bFolders = False, $iMaxDepth = -1, $iDebug = 0)
	;Local $aTmp[1][2] ;das Array das für _FTP_FileList_Rekursiv benötigt wird
	;Local $aSplit
	_FTP_FileList_Rekursiv($l_FTPSession, $aResult, $sPath, $bFolders, $iMaxDepth, $iDebug, True) ;unter 3.3.6.1
	;	_FTP_FileList_Rekursiv($l_FTPSession, $aTmp, $sPath, $bFolders, $iMaxDepth, $iDebug, False);dadurch keine Errors aber der Progress in KB funktioniert nicht
	If $iDebug = 2 Then _ArrayDisplay($aResult, 'Rückgabe _FTP_FileList_Rekursiv') ;kann auskommentiert werden
	;	#comments-start
	If IsArray($aResult) Then
		$aResult[0][0] = UBound($aResult) - 1
		;ReDim $aResult[$aResult[0] + 1][2]
		For $i = 1 To $aResult[0][0]
			$aResult[0][1] += $aResult[$i][1]
		Next
	EndIf
	;	#comments-end
EndFunc   ;==>_FTP_FileList_Rekursiv2D

;===============================================================================
; Function Name:  	_FTP_FileList_Rekursiv($l_FTPSession, $aResult, $sPath, $bFolders=False,$iDebug=0,$b2D=False)
; Description::   	füllt ein Array mit Dateien (und Verzeichnissen wenn $bFolders true) des FTP-Pfades inkl. aller Unterverzeichnisse
; Parameter(s):   	$l_FTPSession	das von _FTP_Connect zurückgegebene Handle
;					$aResult   = das Array in dem die Ergebnisse eingefügt werden
;					$sPath     = Verzeichnispfad, der eingefügt werden soll
;					$bFolders    = True = auch Verzeichnisse einfügen, False = nur Dateien, Default = nur Dateien
;					$iMaxDepth	= <1 = Rekursion bis zum letzten Ästchen, jede andere Zahl stellt die max. Rekursionstiefe ein
;					$iDebug	sollen Debuginfos in der Scitekosole angezeigt werden? Default = 0 = keine, 1=mit, 2)mit + Arraydisplay
;					$b2D als Vorbereutung für _FTP_FileList_Rekursiv2D Default=False
;						wird nur benötigt wenn von _FTP_FileList_Rekursiv2D aufgerufen daher nicht selbst setzen
;					$iDepth für internen Gebrauch daher nicht selbst setzen
; Autor(s):			AutoBert (www.autoit.de)
;					zur freien Benutzung in eigenen Skripten und auch zur freien Weitergabe unter der Vorgabe,
;					dass diese Funktionsbeschreibumg inkl. Autor nicht enfernt wird
;
;					Achtung benötugt bugfreie Version von FTPEx.au3 (3.3.6.1)
;===============================================================================
Func _FTP_FileList_Rekursiv($l_FTPSession, ByRef $aResult, $sPath, $bFolders = False, $iMaxDepth = -1, $iDebug = 0, $b2D = False, $iDepth = 0)
	Local $aFiles, $aFolders
	If $sPath = "/" Then $sPath = ""
	_report($sPath & @TAB & $iDepth & '/' & $iMaxDepth,0,$iDebug)
	If $iMaxDepth > 0 Then
		If $iDepth > $iMaxDepth Then Return
	EndIf
	$iDepth += 1
	If $sPath <> "" Then
		_FTP_DirSetCurrent($l_FTPSession, $sPath)
		If @error Then
			_report("Remoteverzeichnis: " & $sPath & " existiert nicht!",0,$iDebug)
			Return
		Else
			$sPath = _FTP_DirGetCurrent($l_FTPSession)
		EndIf
	EndIf
	$aFiles = _FTP_ListToArray2D($l_FTPSession, 2)
	If IsArray($aFiles) Then
		If $iDebug = 2 Then _ArrayDisplay($aFiles, 'Rückgabe  _Ftp_ListToArray2D')
		If $aFiles[0][0] > 0 Then
			For $i = 1 To $aFiles[0][0]
				If $b2D Then
					_ArrayAdd($aResult, $sPath & "/" & $aFiles[$i][0] & "|" & $aFiles[$i][1])
					_report("File: " & $sPath & "/" & $aFiles[$i][0] & "|" & $aFiles[$i][1],0,$iDebug)
				Else
					_ArrayAdd($aResult, $sPath & "/" & $aFiles[$i][0])
					_report("File: " & $sPath & "/" & $aFiles[$i][0],0,$iDebug)
				EndIf
			Next
		EndIf
	EndIf
	$aFolders = _FTP_ListToArray2D($l_FTPSession, 1)
	If $iDebug = 2 Then _ArrayDisplay($aFolders)
	If IsArray($aFolders) Then
		If $aFolders[0][0] > 0 Then
			For $i = 1 To $aFolders[0][0]
				If $aFolders[$i][0] <> '.' And $aFolders[$i][0] <> '..' Then
					_report("Folder: " & $sPath & "/" & $aFolders[$i][0] & "|" & $aFolders[$i][1],0,$iDebug)
					If $bFolders Then _ArrayAdd($aResult, $sPath & "/" & $aFolders[$i][0] & "|" & $aFolders[$i][1])
					_FTP_FileList_Rekursiv($l_FTPSession, $aResult, $sPath & "/" & $aFolders[$i][0], $bFolders, $iMaxDepth, $iDebug, $b2D, $iDepth)
				EndIf
			Next
		EndIf
	EndIf
EndFunc   ;==>_FTP_FileList_Rekursiv

Func _report($sMsg, $hLog = 0, $iDebug = 0)
	if $hLog <> 0 Then _GUICtrlEdit_AppendText($hLog,$sMsg&@CRLF)
	If $iDebug Then ConsoleWrite($sMsg & @CRLF)
EndFunc   ;==>_report
