Module Module_SaveLoad

    ' =======================================================================================================
    '   APP TITLE AND VERSION
    ' =======================================================================================================
    Friend Function AppTitleAndVersion(Optional ByVal Title As String = "") As String
        If Title = "" Then Title = Replace(My.Application.Info.AssemblyName, "_", " ")
        Dim s() As String = Split(My.Application.Info.Version.ToString, ".")
        Return Title & " - V" & s(0) & "." & s(1)
    End Function

    ' ====================================================================================================
    '  String and Form functions
    ' ====================================================================================================
    Friend Sub StringArray_AddNewString(ByRef StringArray() As String, ByVal NewString As String)
        Dim index As Int32 = StringArray.Count
        ReDim Preserve StringArray(index)
        StringArray(index) = NewString
    End Sub

    Friend Sub StringArray_AddNewStringArray(ByRef StringArray() As String, ByVal NewString() As String)
        Dim index As Int32 = StringArray.Count
        For Each s As String In NewString
            ReDim Preserve StringArray(index)
            StringArray(index) = s
            index += 1
        Next
    End Sub

    Friend Function StrToFloat(ByVal s As String) As Double
        StrToFloat = Val(Replace(s, ",", "."))
    End Function

    Friend Function FloatToStr(ByVal n As Double) As String
        FloatToStr = Trim(Str(n))
        If Left(FloatToStr, 1) = "." Then FloatToStr = "0" & FloatToStr
    End Function

    Friend Function BoolToStr(ByVal b As Boolean) As String
        If b Then
            BoolToStr = "1"
        Else
            BoolToStr = "0"
        End If
    End Function

    Friend Function ExtractParamName(ByRef s As String) As String
        ' ------------------------- Returns the first field from begin to the first "=" symbol
        ' -------------------------  and removes it from the string
        Dim i As Integer
        i = InStr(s, "=")
        If i > 0 Then
            ExtractParamName = Trim(Left(s, i - 1))
            s = Trim(Mid(s, i + 1))
        Else
            ExtractParamName = Trim(s)
            s = ""
        End If
    End Function

    Friend Function ExtractBoolean(ByRef s As String) As Boolean
        ExtractBoolean = Val(s) <> 0
    End Function

    Friend Function ExtractInteger(ByRef s As String, ByVal min As Integer, ByVal max As Integer) As Int32
        ExtractInteger = CInt(Val(s))
        If ExtractInteger < min Then ExtractInteger = min
        If ExtractInteger > max Then ExtractInteger = max
    End Function

    Friend Function ExtractDouble(ByRef s As String, ByVal min As Double, ByVal max As Double) As Double
        ExtractDouble = Val(s)
        If ExtractDouble < min Then ExtractDouble = min
        If ExtractDouble > max Then ExtractDouble = max
    End Function

    Friend Function ExtractSingle(ByRef s As String, ByVal min As Single, ByVal max As Single) As Single
        ExtractSingle = CSng(Val(s))
        If ExtractSingle < min Then ExtractSingle = min
        If ExtractSingle > max Then ExtractSingle = max
    End Function



    ' =======================================================================================
    '  FORM FUNCTIONS
    ' =======================================================================================
    Friend Sub LimitFormPosition(ByVal f As System.Windows.Forms.Form)
        If f.WindowState <> FormWindowState.Normal Then Return
        GetMaxScreenBounds()
        EnsureFormVisible(f)
        'EnsureFormCompletelyVisible(f)
    End Sub

    Private SB As Rectangle = New Rectangle(Integer.MaxValue, Integer.MaxValue, Integer.MinValue, Integer.MinValue)

    Private Sub GetMaxScreenBounds()
        For Each s As Screen In System.Windows.Forms.Screen.AllScreens
            SB = Rectangle.Union(SB, s.WorkingArea)
        Next
    End Sub

    'Private Sub EnsureFormCompletelyVisible(ByVal frm As Form)
    '    With frm
    '        .Width = Math.Min(.Width, SB.Width)         ' not more than a maximized window
    '        .Height = Math.Min(.Height, SB.Height)      ' not more than a maximized window
    '        .Width = Math.Max(.Width, 32)               ' at least 32x24
    '        .Height = Math.Max(.Height, 24)             ' at least 32x24
    '        .Left = Math.Min(.Left, SB.Right - .Width)  ' not beyond the right border
    '        .Top = Math.Min(.Top, SB.Bottom - .Height)  ' not beyond the bottom border
    '        .Left = Math.Max(.Left, SB.Left)            ' at least at the left border
    '        .Top = Math.Max(.Top, SB.Top)               ' at least at the top border
    '    End With
    'End Sub

    Private Sub EnsureFormVisible(ByVal frm As Form)
        With frm
            .Width = Math.Min(.Width, SB.Width)             ' not more than VIRTUALSCREEN dimensions
            .Height = Math.Min(.Height, SB.Height)          ' not more than VIRTUALSCREEN dimensions 
            .Width = Math.Max(.Width, 32)                   ' at least 32x24
            .Height = Math.Max(.Height, 24)                 ' at least 32x24
            .Left = Math.Min(.Left, SB.Right - 50)          ' not beyond right border - 50 pixels
            .Top = Math.Min(.Top, SB.Bottom - 100)          ' not beyond bottom border - 50 pixels
            .Left = Math.Max(.Left, SB.Left + 100 - .Width) ' at least at left border + 50 pixels
            .Top = Math.Max(.Top, SB.Top - 10)              ' at least at top border
        End With
    End Sub

    ' (The value of the RestoreBounds property is valid only 
    '   when the WindowState property of the Form class is not equal to Normal)
    Friend Function GetFormRectangle(ByVal frm As Form) As Rectangle
        Dim r As Rectangle
        If frm.WindowState = FormWindowState.Normal Then
            r = frm.Bounds
        Else
            r = frm.RestoreBounds
        End If
        Return r
    End Function



    ' ==================================================================================================
    '  SAVE LOAD -- USER OPTIONS
    ' ==================================================================================================
    Friend Sub SaveUserOptions()
        '
        Dim TempFile As String = My.Application.Info.DirectoryPath & "\UserOptions_Temp.txt"
        File_KillFile(TempFile)
        Dim f As Int32 = FreeFile()
        '
        Try
            FileOpen(f, TempFile, OpenMode.Output, OpenAccess.Write)
            PrintLine(f, "User options")
            PrintLine(f, "======================================")
            ' ------------------------------------------------------------------------------ FORM1 BOUNDS
            Dim r As Rectangle = GetFormRectangle(Form_Main)
            PrintLine(f, "Top=", TAB(30), FloatToStr(r.Top))
            PrintLine(f, "Left=", TAB(30), FloatToStr(r.Left))
            PrintLine(f, "Width=", TAB(30), FloatToStr(r.Width))
            PrintLine(f, "Height=", TAB(30), FloatToStr(r.Height))
            PrintLine(f, "WindowState=", TAB(30), FloatToStr(Form_Main.WindowState))
            '
            ' ------------------------------------------------------------------------------
            PrintLine(f, "SelectedFtp=", TAB(30), FloatToStr(SelectedFtp))
            PrintLine(f, "AutomaticPath=", TAB(30), BoolToStr(Form_Main.CheckBox_AutoHttp.Checked))
            '
            FileClose(f)
            ' ------------------------------------------------------------------ copy the temp file on the main file
            My.Computer.FileSystem.CopyFile(TempFile, My.Application.Info.DirectoryPath & "\UserOptions.txt", True)
            File_KillFile(TempFile)
            '
        Catch
        End Try
        Try
            FileClose(f)
            File_KillFile(TempFile)
        Catch
        End Try
    End Sub

    Friend Sub LoadUserOptions()
        ' ------------------------------------------------------------- form1
        Form_Main.Top = 0
        Form_Main.Left = 0
        Form_Main.Width = 0
        Form_Main.Height = 0
        ' ------------------------------------------------------------- 
        Form_Main.CheckBox_AutoHttp.Checked = True
        ' -------------------------------------------------- Leggo i parametri
        Dim l As String
        Dim file As String
        file = My.Application.Info.DirectoryPath & "\UserOptions.txt"
        If FileExists(file) Then
            Dim f As Int32 = FreeFile()
            FileOpen(f, file, OpenMode.Input, OpenAccess.Read, OpenShare.Shared)
            Do While Not EOF(f)
                l = LineInput(f)
                Select Case ExtractParamName(l)
                    ' ------------------------------------------------- form CoreMain
                    Case "Top" : Form_Main.Top = ExtractInteger(l, 0, 10000)
                    Case "Left" : Form_Main.Left = ExtractInteger(l, 0, 10000)
                    Case "Width" : Form_Main.Width = ExtractInteger(l, 0, 10000)
                    Case "Height" : Form_Main.Height = ExtractInteger(l, 0, 10000)
                    Case "WindowState" : Form_Main.WindowState = DirectCast(ExtractInteger(l, 0, 2), FormWindowState)
                        '
                    Case "SelectedFtp" : SelectedFtp = ExtractInteger(l, 0, 999)

                End Select
            Loop
            FileClose(f)
        End If
        LimitFormPosition(Form_Main)
    End Sub



    ' ==================================================================================================
    '  SAVE LOAD -- FTP INFO
    ' ==================================================================================================
    Friend SelectedFtp As Int32 = 0
    Friend FtpInfo(-1) As FtpInfo_Struct

    Friend Structure FtpInfo_Struct
        Dim UserName As String
        Dim Password As String
        Dim FTP_Folder As String
        Dim HTTP_Folder As String
        Dim AutoHttpPath As Boolean
    End Structure

    Friend Sub FTPData_To_FormControls(ByVal index As Int32)
        If index < 0 Or index > FtpInfo.GetLength(0) - 1 Then Exit Sub
        With FtpInfo(index)
            Form_Main.txtUserName.Text = .UserName
            Form_Main.txtPassword.Text = .Password
            Form_Main.txtFtpFolder.Text = .FTP_Folder
            Form_Main.txtHttpFolder.Text = .HTTP_Folder
            Form_Main.CheckBox_AutoHttp.Checked = .AutoHttpPath
        End With
    End Sub

    Friend Sub FormControls_To_FTPData(ByVal index As Int32)
        If index < 0 Or index > FtpInfo.GetLength(0) - 1 Then Exit Sub
        With FtpInfo(index)
            .UserName = Form_Main.txtUserName.Text
            .Password = Form_Main.txtPassword.Text
            .FTP_Folder = Form_Main.txtFtpFolder.Text
            .HTTP_Folder = Form_Main.txtHttpFolder.Text
            .AutoHttpPath = Form_Main.CheckBox_AutoHttp.Checked
        End With
    End Sub

    Friend Sub DeleteFtpInfo(ByVal index As Int32)
        If index < 0 Or index > FtpInfo.GetLength(0) - 1 Then Exit Sub
        For i As Int32 = index To FtpInfo.Count - 2
            FtpInfo(i) = FtpInfo(i + 1)
        Next
        ReDim Preserve FtpInfo(FtpInfo.GetLength(0) - 2)
    End Sub

    Friend Sub ClearPrivateData()
        For i As Int32 = 0 To FtpInfo.Count - 1
            FtpInfo(i).UserName = ""
            FtpInfo(i).Password = ""
        Next
    End Sub

    Friend Sub StoreFTPData()
        ' ------------------------------------------------- if existing update and save
        For i As Int32 = 0 To FtpInfo.Count - 1
            If FtpInfo(i).FTP_Folder = Form_Main.txtFtpFolder.Text Then
                FormControls_To_FTPData(i)
                Save_FtpInfo()
                Exit Sub
            End If
        Next
        ' ------------------------------------------------- if not existing add and save
        Dim index As Int32 = FtpInfo.GetLength(0)
        ReDim Preserve FtpInfo(index)
        FormControls_To_FTPData(index)
        Save_FtpInfo()
        SelectedFtp = index
    End Sub

    Friend Sub Save_FtpInfo()
        Dim file As String
        file = My.Application.Info.DirectoryPath & "\FtpInfo.txt"
        File_KillFile(file)
        Dim f As Int32 = FreeFile()
        FileOpen(f, file, OpenMode.Output, OpenAccess.Write)
        For i As Int32 = 0 To FtpInfo.GetLength(0) - 1
            PrintLine(f, "==========================================================================")
            PrintLine(f, "FTP INFO")
            PrintLine(f, "==========================================================================")
            PrintLine(f, "FTP_Folder=", TAB(20), FtpInfo(i).FTP_Folder)
            PrintLine(f, "UserName=", TAB(20), FtpInfo(i).UserName)
            PrintLine(f, "Password=", TAB(20), FtpInfo(i).Password)
            PrintLine(f, "HTTP_Folder=", TAB(20), FtpInfo(i).HTTP_Folder)
            PrintLine(f, "AutomaticPath=", TAB(20), BoolToStr(FtpInfo(i).AutoHttpPath))
            PrintLine(f, "")
        Next
        FileClose(f)
    End Sub

    Friend Sub Load_FtpInfo()
        Dim index As Int32
        Dim s1, s2 As String
        Dim file As String
        file = My.Application.Info.DirectoryPath & "\FtpInfo.txt"
        If FileExists(file) Then
            Try
                ReDim FtpInfo(-1)
                Dim f As Int32 = FreeFile()
                FileOpen(f, file, OpenMode.Input)
                Do While Not EOF(f)
                    s1 = Trim((LineInput(f)))
                    s2 = ExtractParamName(s1)
                    Select Case s2
                        Case "FTP INFO"
                            index = FtpInfo.GetLength(0)
                            ReDim Preserve FtpInfo(index)
                            '
                        Case "FTP_Folder" : FtpInfo(index).FTP_Folder = s1
                        Case "UserName" : FtpInfo(index).UserName = s1
                        Case "Password" : FtpInfo(index).Password = s1
                        Case "HTTP_Folder" : FtpInfo(index).HTTP_Folder = s1
                        Case "AutomaticPath" : FtpInfo(index).AutoHttpPath = ExtractBoolean(s1)
                            '
                    End Select
                Loop
                FileClose(f)
            Catch
                MsgBox("Error reading the file: ""FtpInfo.txt""")
            End Try
        End If

        'If FtpInfo.GetLength(0) = 0 Then
        '    ReDim FtpInfo(0)
        '    SetThemeDefaults(FtpInfo(0))
        'End If
    End Sub



    ' ==================================================================================================
    '  SAVE LOAD -- Regular Expressions
    ' ==================================================================================================
    Friend RegExp As String()

    Private Sub SetDefaultRegexp()
        ' ---------------------------------------------- RegExp with "usernum" and "users" fields
        RegExp = New String() _
        { _
        "(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})(?<usernum>\s+\d+)(?<users>\s+\w+\s+\w+\s+)(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{4})\s+(?<name>.+)", _
        "(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})(?<usernum>\s+\d+)(?<users>\s+\w+\s+\w+\s+)(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{1,2}:\d{2})\s+(?<name>.+)", _
        "(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})(?<usernum>\s+\d+)(?<users>\s+\d+\s+)(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{4})\s+(?<name>.+)", _
        "(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})(?<usernum>\s+\d+)(?<users>\s+\d+\s+)(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{1,2}:\d{2})\s+(?<name>.+)", _
        "(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})(\s+)(?<size>(\d+))(\s+)(?<ctbit>(\w+\s\w+))(\s+)(?<size2>(\d+))\s+(?<timestamp>\w+\s+\d+\s+\d{2}:\d{2})\s+(?<name>.+)", _
        "(?<timestamp>\d{2}\-\d{2}\-\d{2}\s+\d{2}:\d{2}[Aa|Pp][mM])\s+(?<dir>\<\w+\>){0,1}(?<size>\d+){0,1}\s+(?<name>.+)", _
        "(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})(?<usernum>\s+\d+)(?<users>\s+\w+\.+\w+\s+\w+\s+)(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{4})\s+(?<name>.+)", _
        "(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})(?<usernum>\s+\d+)(?<users>\s+\w+\.+\w+\s+\w+\s+)(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{1,2}:\d{2})\s+(?<name>.+)" _
        }
    End Sub



    Friend Sub Save_RegularExpressions()
        Dim file As String
        file = My.Application.Info.DirectoryPath & "\RegExp.txt"
        File_KillFile(file)
        Dim f As Int32 = FreeFile()
        FileOpen(f, file, OpenMode.Output, OpenAccess.Write)
        PrintLine(f, "==============================================================================================")
        PrintLine(f, "  ""Regular Epressions"" used to decode directory lines")
        PrintLine(f, "==============================================================================================")
        PrintLine(f, "")
        PrintLine(f, "   A large number of directory formats are well decoded with the following expressions")
        PrintLine(f, "  but since UNIX / LINUX and DOS sites are using many undocumented directory formats")
        PrintLine(f, "  new directory formats can be implemented adding new lines or editing them.")
        PrintLine(f, "")
        PrintLine(f, "  The expressions are used to extract the following groups:")
        PrintLine(f, "   - dir")
        PrintLine(f, "   - permission")
        PrintLine(f, "   - usernum")
        PrintLine(f, "   - users")
        PrintLine(f, "   - timestamp")
        PrintLine(f, "   - name")
        PrintLine(f, "")
        PrintLine(f, "  Lines 1 to 4 are used for the most usual formats")
        PrintLine(f, "  Lines 5 to 6 are used for strange formats without the ""users"" informations ")
        PrintLine(f, "  Lines 7 to 8 are used for the strange ""users"" format used by the ""Register.it"" provider")
        PrintLine(f, "")
        PrintLine(f, "  To restore the default formats delete this file and then open and close the FastFTP program.")
        PrintLine(f, "")
        PrintLine(f, "==============================================================================================")
        For i As Int32 = 0 To RegExp.Count - 1
            PrintLine(f, "RegExp= " & RegExp(i))
        Next
        FileClose(f)
    End Sub

    Friend Sub Load_RegularExpressions()
        ReDim RegExp(-1)
        Dim index As Int32
        Dim s1 As String
        Dim file As String
        file = My.Application.Info.DirectoryPath & "\RegExp.txt"
        If FileExists(file) Then
            Try
                Dim f As Int32 = FreeFile()
                FileOpen(f, file, OpenMode.Input)
                Do While Not EOF(f)
                    s1 = Trim((LineInput(f)))
                    Select Case ExtractParamName(s1)
                        Case "RegExp"
                            index = RegExp.Count
                            ReDim Preserve RegExp(index)
                            RegExp(index) = s1
                    End Select
                Loop
                FileClose(f)
            Catch
                MsgBox("Error reading the file: ""FtpInfo.txt""")
            End Try
        End If

        If RegExp.Count = 0 Then SetDefaultRegexp()
    End Sub



End Module
