#Include "ftp.bi"
Dim Shared As ftp_ctx ftp

'FTP
'Declares are HERE because of using ftp_ctx
Declare Sub RefreshFTPFiles(byval ctx as ftp_ctx Ptr,ByVal DirDirection As Integer=0)
Declare Function FT2Dbl(FT As FILETIME) As Double
Declare Sub FTPClose(Keep As BOOL)
Declare Sub ChangeFTPDir(ByVal DirWant As String)
Declare Function FTPDirComm(FromPath As String,ToPath As String,TheFolder As String,Action As String) As Integer
'next 3 recursive folder functions
Declare Function deletefolderftp( ByVal ctx As ftp_ctx Ptr, ByVal folder As String) As Integer
Declare Function UploadFolder(ByVal ctx As ftp_ctx Ptr,TheFolder As String) As Integer
Declare Function DownloadFolder(ByVal ctx As ftp_ctx Ptr,TheFolder As String) As Integer
'
Sub RefreshFTPFiles(ByVal ctx As ftp_ctx Ptr,ByVal DirDirection As Integer=0)
	ReDim FTPR(0) As FileStats
	Dim hFind As HINTERNET
	Dim dirInfo As WIN32_FIND_DATA
	Dim As Integer DCount,FCount,x
	Dim As Double Server2Local
	Static As Integer Deep
	Deep += DirDirection
	'
	'only want to run this once per connection
	If ctx->TZOffset > 50 Then
		Dim As String F
		Dim As Double DT
		'see if test file exists
		LogFTP "Getting Time Zone offset for server"
		Do
			F = "TimeZoneTest"+Str(x)+".txt"
			hFind = FtpFindFirstFile( ctx->hconn, F, @dirInfo, NULL, 0 )
			If hFind = NULL Then
				'this file does not exist or no file entries??
				InternetCloseHandle(hFind)
				Exit Do
			Else
				'this one exists...for some reason?
				InternetCloseHandle(hFind)
				x += 1
			EndIf
		Loop Until x = 10 'no infinite loop
		If x = 10 Then
			'something didn't work ...
			MessageBox(0,"Showing server time","Could not get time zone offset",MB_OK)
		Else
			'create temp test file
			x = FreeFile
			Open ExePath+Path_Delim+F For Output As #x
			Print #x, F 'something to send ... could have left it a zero byte file?
			Close #x
			'write the file
			x = ftp_putfile(ctx,ExePath+Path_Delim+F,F) 'returns 0 if Error
			'if x=0 then not a writeable folder???
			If x Then
				'get file info
				hFind = FtpFindFirstFile( ctx->hconn, F, @dirInfo, NULL, 0 )
				InternetCloseHandle(hFind)
				'calc time difference
				'get "server" time 
				DT = FT2Dbl(dirInfo.ftLastWriteTime)
				DCount = DateDiff("n",Now,DT) 'n is number of MINUTES (h rounds to next hour)
				'may be off by 1-2 minutes
				If DCount > 0 Then
					DCount += 5
				Else
					DCount -= 5
				EndIf
				ctx->TZOffset = Fix(DCount/60)
				LogFTP "Time zone difference of "+Str(ctx->TZOffset)+" hours."
				'delete the file
				x = ftp_deletefile(ctx,F)
			Else
				LogFTP "Could not get offset at this time."
			EndIf
			Kill ExePath+Path_Delim+F
		EndIf
	EndIf
	'
	LogFTP "List"
	hFind = FtpFindFirstFile( ctx->hconn, "*.*", @dirInfo, NULL, 0 )
	If hFind = NULL Then
		InternetCloseHandle(hFind)
		MessageBox(0,"Find file error","Oops!",MB_OK Or MB_ICONERROR)
		Exit Sub
	EndIf
	'
	DCount = 0
	Do
		If dirInfo.cFileName <> "." And dirInfo.cFileName <> ".." Then
			ReDim Preserve FTPR(DCount) As FileStats
			FTPR(DCount).FName = dirInfo.cFileName
			FTPR(DCount).Att = dirInfo.dwFileAttributes
			'
			Server2Local = FT2Dbl(dirInfo.ftLastWriteTime)
			FTPR(DCount).DT = DateAdd("h",ctx->TZOffset,Server2Local)
			'
			Server2Local = FT2Dbl(dirInfo.ftLastAccessTime)
			FTPR(DCount).LastAccess = DateAdd("h",ctx->TZOffset,Server2Local)
			'
			Server2Local = FT2Dbl(dirInfo.ftCreationTime)
			FTPR(DCount).Create = DateAdd("h",ctx->TZOffset,Server2Local)
			'
			FTPR(DCount).FName83 = dirInfo.cAlternateFileName
			If (dirInfo.dwFileAttributes And 16) = 16 Then
				FTPR(DCount).Ext = "File Folder"
			Else
				FTPR(DCount).FSize = (dirInfo.nFileSizeHigh * MAXDWORD) + dirInfo.nFileSizeLow
				x = InStrRev(dirInfo.cFileName,".")
				If x Then
					FTPR(DCount).Ext = UCase(Mid(dirInfo.cFileName,x+1)) 'has extention
				Else
					FTPR(DCount).Ext = "FILE"
				EndIf
			EndIf
			DCount += 1
		EndIf
	Loop Until ( InternetFindNextFile( hFind, @dirInfo ) = FALSE )
	InternetCloseHandle(hFind)
	ftp.LastFTP = Timer
	'some ftp servers do not send ".." so make one!
	If Deep Then
		ReDim Preserve FTPR(DCount) As FileStats
		FTPR(DCount).FName = ".."
		FTPR(DCount).Ext = "File Folder"
		FTPR(DCount).Att = 16
	EndIf
	'
	RefreshBottomLV
End Sub

'converts WIN32_FIND_DATA filetimes to a usable double/datetimeserial
Function FT2Dbl(FT As FILETIME) As Double
	Dim As SYSTEMTIME stLocal
	Dim As FILETIME LFT
	FileTimeToLocalFileTime(@FT,@LFT)
	FileTimeToSystemTime(@LFT, @stLocal)
	'SystemTimeToTzSpecificLocalTime(NULL, @stUTC, @stLocal)
	With stLocal
		Function = DateSerial(.wYear,.wMonth,.wDay)+TimeSerial(.wHour,.wMinute,.wSecond)
	End With
End Function

'ending a FTP session
Sub FTPClose(Keep As BOOL)
	ftp_close(@ftp)
	'now clean up
	Dim As String R,F
	Dim As Integer x
	'remove any files
	x = InStrRev(FTPTemp,Path_Delim)
	R = Left(FTPTemp,x)
	F = Mid(FTPTemp,x+1)
	'get file names to delete
	x = DW_AllDir(R,F)
	For x = 0 To UBound(DW_Files)
		'kill each file
		If DW_Files(x)<>"" Then Kill DW_Files(x)
	Next
	For x = 0 To UBound(DW_Folders)
		'kill each folder
		If DW_Files(x)<>"" Then RmDir(DW_Folders(x))
	Next
	RmDir(FTPTemp)
	'save each session log
	If Keep Then
		'rename
		Dim As String NewName
		'sample first line --> 20:28:16 Connected: ftp.xyx.com\sub\sub2\
		x = FreeFile
		Open ExePath + Path_Delim + "FTPSession.txt" For Input As #x
		Line Input #x, R
		Close #x
		NewName = str_parse(R," ",3)
		'remove any slashes
		x = InStr(NewName,Any "\/")
		'if so, change them
		If x Then NewName = str_ReplaceAnyAll("\/","-",NewName)
		'assume same day
		NewName += Right(Date,4)+Left(Date,2)+Mid(Date,4,2)
		F = str_parse(R," ",1)
		NewName += Format(TimeValue(F), "hhmmss")+".txt"
		Name ExePath + Path_Delim + "FTPSession.txt",NewName
	Else
		Kill ExePath + Path_Delim + "FTPSession.txt"
	EndIf
	ReDim DW_Folders(0),DW_Files(0)
End Sub

Sub ChangeFTPDir(ByVal DirWant As String)
	Static As Integer LevelDeep
	Dim As Integer R
	Dim As ZString * MAX_PATH z
	'This shouldn't happen ....
	If LevelDeep = 0 And DirWant = ".." Then Exit Sub
	'
	R = ftp_changedir(@ftp,DirWant)
	If R = 0 Then
		LogFTP "Error changing directories"
		Exit Sub
	EndIf
	LogFTP "Directory changed to: "+DirWant
	'use this function for updating status of bottom
	R = MAX_PATH 'must be set to num char to get
	If FtpGetCurrentDirectory(ftp.hconn,@z,@R) Then
		SetWindowText(PDispBottom,z)
		Beep
	EndIf
	If DirWant = ".." Then
		LevelDeep -= 1
		RefreshFTPFiles @ftp,-1
	Else
		LevelDeep += 1
		RefreshFTPFiles @ftp,1
	EndIf
End Sub

Function FTPDirComm(FromPath As String,ToPath As String,AFolder As String,Action As String) As Integer
	Dim As String HoldDir,K
	Dim As Integer x
	'
	K = AFolder
	If Action = "moved" Or Action = "copied" Then
		HoldDir = CurDir
		If FromPath = "FTP" Then
			ChDir ToPath
			x=DownloadFolder(@ftp,K)
			If x Then LogFTP "Folder "+K+" downloaded."
		Else
			ChDir FromPath
			x=UploadFolder(@ftp,K)
			If x Then LogFTP "Folder "+K+" uploaded."
		EndIf
		ChDir HoldDir
	EndIf
	If x=0 Then Return 1
	If Action = "moved" Or Action = "deleted" Then
		If FromPath = "FTP" Then
			x=deletefolderftp(@ftp,K)
			If x Then LogFTP "Folder "+K+" deleted."
			If x=0 Then
				x = 1
			Else
				x = 0
			EndIf
		Else
			'returns nonzero if error
			x=DoDirComm(FromPath,FromPath,K,"deleted") 'this will also take care of trees
		EndIf
	EndIf
	'0 on no error
	Return x
End Function

'recursive ftp dir dele
Function deletefolderftp( ByVal ctx As ftp_ctx Ptr, ByVal folder As String) As Integer
	Dim findf As HINTERNET
	Dim dirInfo As WIN32_FIND_DATA
	ReDim As String folderlist(0), filelist(0)
	Dim aa As Integer
	'
	If FtpSetCurrentDirectory(ctx->hconn,folder) = FALSE Then Return FALSE
	'
	findf = FtpFindFirstFile( ctx->hconn, "*", @dirInfo, NULL, 0 )
	If findf = NULL Then
		'Error in folder entry?
		InternetCloseHandle(findf)
		Return FALSE
	EndIf
	'
	folderlist(0)=""
	Do
		If dirInfo.cFileName<>"." and dirInfo.cFileName<>".." Then
			If (dirInfo.dwFileAttributes And 16) = 16 Then
				folderlist(UBound(folderlist))=dirInfo.cFileName
				ReDim Preserve folderlist(UBound(folderlist)+1) As string
			Else
				filelist(UBound(filelist))=dirInfo.cFileName
				ReDim Preserve filelist(UBound(filelist)+1) As String
			EndIf
		EndIf
	Loop Until ( InternetFindNextFile( findf, @dirInfo ) = FALSE )

	InternetCloseHandle(findf)

	For aa = 0 To UBound(filelist)
		If Len(filelist(aa)) Then FtpDeleteFile(ctx->hconn,filelist(aa))
	Next

	For aa = 0 To UBound(folderlist)
		If Len(folderlist(aa)) Then deletefolderftp(ctx, folderlist(aa))
	Next

	FtpSetCurrentDirectory(ctx->hconn,"..")
	FtpRemoveDirectory( ctx->hconn, folder )
	Function = TRUE
End Function

'next 2 use relative paths
Function DownloadFolder(ByVal ctx As ftp_ctx Ptr,TheFolder As String) As Integer
	Dim findf As HINTERNET
	Dim dirInfo As WIN32_FIND_DATA
	ReDim As String folderlist(0), filelist(0)
	Dim aa As Integer
	'
	If FtpSetCurrentDirectory(ctx->hconn,TheFolder) Then
		MkDir(TheFolder)
		ChDir(TheFolder)
	Else
		Return FALSE
	EndIf
	'
	findf = FtpFindFirstFile( ctx->hconn, "*", @dirInfo, NULL, 0 )
	If findf = NULL Then
		'Error in folder entry?
		InternetCloseHandle(findf)
		Return FALSE
	EndIf
	'
	folderlist(0)=""
	Do
		If dirInfo.cFileName<>"." and dirInfo.cFileName<>".." Then
			If (dirInfo.dwFileAttributes And 16) = 16 Then
				folderlist(UBound(folderlist))=dirInfo.cFileName
				ReDim Preserve folderlist(UBound(folderlist)+1) As string
			Else
				filelist(UBound(filelist))=dirInfo.cFileName
				ReDim Preserve filelist(UBound(filelist)+1) As String
			EndIf
		EndIf
	Loop Until ( InternetFindNextFile( findf, @dirInfo ) = FALSE )
	InternetCloseHandle(findf)
	'
	For aa = 0 To UBound(filelist)
		If Len(filelist(aa)) Then ftp_getfile(ctx,filelist(aa),filelist(aa))
	Next
	For aa = 0 To UBound(folderlist)
		If Len(folderlist(aa)) Then DownloadFolder(ctx,folderlist(aa))
	Next
	'
	FtpSetCurrentDirectory(ctx->hconn,"..")
	ChDir("..")
	Function = TRUE
End Function

Function UploadFolder(ByVal ctx As ftp_ctx Ptr,TheFolder As String) As Integer
	Dim As String F
	ReDim As String folderlist(0), filelist(0)
	Dim aa As Integer
	'
	If FtpCreateDirectory(ctx->hconn,TheFolder)=0 Then Return FALSE
	If FtpSetCurrentDirectory(ctx->hconn,TheFolder) Then
		ChDir(TheFolder)
	Else
		Return FALSE
	EndIf
	'
	F = Dir(TheFolder & "*",55,@aa)
	While F <> ""
		If F<>"." and F<>".." Then
			If (aa And 16) = 16 Then
				folderlist(UBound(folderlist))=F
				ReDim Preserve folderlist(UBound(folderlist)+1) As string
			Else
				filelist(UBound(filelist))=F
				ReDim Preserve filelist(UBound(filelist)+1) As String
			EndIf
		EndIf
		'
		F = Dir()
	Wend
	'
	For aa = 0 To UBound(filelist)
		If Len(filelist(aa)) Then ftp_putfile(ctx,filelist(aa),filelist(aa))
	Next
	For aa = 0 To UBound(folderlist)
		If Len(folderlist(aa)) Then UploadFolder(ctx,folderlist(aa))
	Next
	'
	FtpSetCurrentDirectory(ctx->hconn,"..")
	ChDir("..")
	Function = TRUE
End Function

'dir walker for ftp (must have XDirWalk.bi)
Function DW_Dir_FTP(ByVal ctx As ftp_ctx Ptr,Fold As String) As Integer
	Dim findf As HINTERNET
	Dim dirInfo As WIN32_FIND_DATA
	ReDim As String folderlist(0)
	Dim As Integer aa, Ub, RetSize
	'
	If FtpSetCurrentDirectory(ctx->hconn,Fold) = FALSE Then Return 0
	'
	findf = FtpFindFirstFile( ctx->hconn, "*", @dirInfo, NULL, 0 )
	If findf = NULL Then
		'Error in folder entry?
		InternetCloseHandle(findf)
		Return 0
	EndIf
	'
	folderlist(0)=""
	Do
		If dirInfo.cFileName<>"." and dirInfo.cFileName<>".." Then
			If (dirInfo.dwFileAttributes And 16) = 16 Then
				folderlist(UBound(folderlist))=dirInfo.cFileName
				ReDim Preserve folderlist(UBound(folderlist)+1) As string
				'add to folder array
				Ub = UBound(DW_Folders)+1
				ReDim Preserve DW_Folders(Ub)
				DW_Folders(Ub) = Fold+dirInfo.cFileName+Path_Delim 'could put anything in here...
			Else
				'add to file array and get size
				Ub = UBound(DW_Files)+1
				ReDim Preserve DW_Files(Ub)
				DW_Files(Ub) = dirInfo.cFileName 'could put anything in here...
				RetSize += (dirInfo.nFileSizeHigh * MAXDWORD) + dirInfo.nFileSizeLow
			EndIf
		EndIf
	Loop Until ( InternetFindNextFile( findf, @dirInfo ) = FALSE )
	InternetCloseHandle(findf)
	'
	For aa = 0 To UBound(folderlist)
		If Len(folderlist(aa)) Then DW_Dir_FTP(ctx,folderlist(aa))
	Next
	'
	FtpSetCurrentDirectory(ctx->hconn,"..")
	Return RetSize
End Function

Function DW_AllDir_FTP(Fold As String) As Integer
	Dim As Integer C
	'clear out any prior run
	ReDim As String DW_Files(0),DW_Folders(0)
	'save init folder
	DW_Folders(0) = Fold+Path_Delim
	'call the walker
	C = DW_Dir_FTP(@ftp,Fold)
	ftp.LastFTP = Timer
	Return C
End Function

/'
FtpCommand
FtpCreateDirectory
FtpDeleteFile
FtpFindFirstFile
FtpGetCurrentDirectory
FtpGetFile
FtpGetFileSize
FtpOpenFile
FtpPutFile
FtpRemoveDirectory
FtpRenameFile
FtpSetCurrentDirectory
'/