Imports System.Collections.ObjectModel
Imports System.ComponentModel
Imports System.Net
Imports System.Security.Cryptography

Public Class Form1
    Public WithEvents client As New Net.WebClient
    Public WithEvents cu As New ClassUnzip
    Public publickey = ""
#Region "Fenster verschieben"
    Dim mouseOffset As Point

    Private Sub Me_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseDown
        mouseOffset = New Point(-e.X, -e.Y)
    End Sub

    Private Sub Me_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseMove

        If e.Button = MouseButtons.Left Then
            Dim mousePos = Control.MousePosition
            mousePos.Offset(mouseOffset.X, mouseOffset.Y)
            Location = mousePos
        End If
    End Sub
    Private Declare Function ReleaseCapture Lib "user32" () As Integer
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (
        ByVal hwnd As Integer,
        ByVal wMsg As Integer,
        ByVal wParam As Integer,
        ByRef lParam As Object) As Integer

    Private Const HTCAPTION As Short = 2
    Private Const WM_NCLBUTTONDOWN As Short = &HA1S
    Private Const WM_SYSCOMMAND As Short = &H112S

    Private Sub Label1_MouseDown(ByVal eventSender As System.Object, ByVal eventArgs As System.Windows.Forms.MouseEventArgs) Handles txt_title.MouseDown
        ReleaseCapture()
        SendMessage(Me.Handle.ToInt32, WM_NCLBUTTONDOWN, HTCAPTION, 0)
    End Sub

#End Region
#Region "FormEvents"

    Dim acttabcontrol As TabPage
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'MsgBox(publickey)
        txt_title.Text = "FPH OMSI-Map Installer für " & My.Resources.MapName
        Text = "FPH OMSI-Map Installer für " & My.Resources.MapName

        lbl_s1_caption.Text = "Dieser Assistent wird sie durch die Installation der OMSI-Karte " & My.Resources.MapName & " führen."
        lbl_s7_caption.Text = My.Resources.MapName & " wurde erfolgreich installiert." & vbNewLine & "Wir wünschen Ihnen viel Spaß mit der Karte!"

        MetroTabControl1.DoAnimation = False
        MetroTabControl1.SelectedTab = tp_2
        MetroTabControl1.SelectedTab = tp_3
        MetroTabControl1.SelectedTab = tp_4
        MetroTabControl1.SelectedTab = tp_5
        MetroTabControl1.SelectedTab = tp_6
        MetroTabControl1.SelectedTab = tp_7
        acttabcontrol = tp_1
        MetroTabControl1.SelectedTab = tp_1

        If My.Computer.FileSystem.DirectoryExists(path) Then
            My.Computer.FileSystem.DeleteDirectory(path, FileIO.DeleteDirectoryOption.DeleteAllContents)
        End If
        My.Computer.FileSystem.CreateDirectory(path)

        client.DownloadFile(My.Resources.URL_picture, path & "\image.jpg")

        pb_s3.Image = Image.FromFile(path & "\image.jpg")
        pb_s4.Image = Image.FromFile(path & "\image.jpg")

        rtb_license.Text = client.DownloadString(My.Resources.URL_License)

        txt_s1_omsipath_TextChanged()
    End Sub

    Sub changeTab(ByVal tp As TabPage)
        MetroTabControl1.DoAnimation = True
        acttabcontrol = tp
        MetroTabControl1.SelectedTab = tp
        MetroTabControl1.DoAnimation = False
    End Sub
    Private Sub cmd_s1_weiter_Click(sender As Object, e As EventArgs) Handles cmd_s1_weiter.Click
        Try
            Dim user As String = client.DownloadString("https://www.fphst.de/nc/Freyfurt/check.php?key=" & txt_s1_key.Text)
            If user.StartsWith("User ") Then
                lbl_user.Text = user.Substring(5).Trim.Replace("<br>", "")
                changeTab(tp_2)
            ElseIf user.StartsWith("Used ")
                MsgBox("Der eingegebene Key wurde bereits am " & user.Substring(5).Trim.Replace("<br>", "") & " benutzt.")
            Else
                MsgBox("Der eingegebene Key ist nicht gültig.")
            End If
        Catch ex As Exception
            MsgBox("Fehler beim Überprüfen auf den Entschlüsselungskey.")
        End Try
    End Sub

    Private Sub MetroTabControl1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles MetroTabControl1.SelectedIndexChanged
        MetroTabControl1.SelectedTab = acttabcontrol
    End Sub

    Private Sub cmd_s2_zuruck_Click(sender As Object, e As EventArgs)
        changeTab(tp_1)
    End Sub

    Private Sub MetroLinkLabel1_Click(sender As Object, e As EventArgs) Handles MetroLinkLabel1.Click
        Process.Start("https://www.fphst.de")
    End Sub

    Private Sub MetroLinkLabel2_Click(sender As Object, e As EventArgs) Handles MetroLinkLabel2.Click
        Process.Start("https://www.fphst.de")
    End Sub
#End Region
#Region "Download"
    Dim dlstate As Integer = 0

    Private Sub client_DownloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs) Handles client.DownloadProgressChanged
        If dlstate = 0 Then
            pb_s3_progress.Value = e.ProgressPercentage
            lbl_s3_progress.Text = "Lade Karte: " & byteView(e.BytesReceived) & " von " & byteView(e.TotalBytesToReceive) & " heruntergeladen."
        ElseIf dlstate = 1
            lbl_s3_progress.Text = "Lade Hof-Datei ..."
        ElseIf dlstate = 2
            lbl_s3_progress.Text = "Lade aiLists ..."
        End If
    End Sub
    Private Sub client_DownloadFileCompleted(sender As Object, e As AsyncCompletedEventArgs) Handles client.DownloadFileCompleted
        If dlstate = 0 Then
            dlstate = 1
            client.DownloadFileAsync(New Uri(My.Resources.URL_Hof), path & "\" & My.Resources.MapName & ".hof")
        ElseIf dlstate = 1
            dlstate = 2
            client.DownloadFileAsync(New Uri(My.Resources.URL_ailists), path & "\ailists.zip")
        ElseIf dlstate = 2
            dlstate = 3
            bgw_install.RunWorkerAsync()
            client.DownloadString("https://www.fphst.de/nc/Freyfurt/downloaded.php?key=" & txt_s1_key.Text)
            changeTab(tp_4)
        End If
    End Sub

    Function byteView(ByVal bytes As Long) As String
        Dim DoubleBytes As Double
        Try
            Select Case bytes
                Case Is >= 1099511627776
                    DoubleBytes = CDbl(bytes / 1099511627776) 'TB
                    Return FormatNumber(DoubleBytes, 2) & " TB"
                Case 1073741824 To 1099511627775
                    DoubleBytes = CDbl(bytes / 1073741824) 'GB
                    Return FormatNumber(DoubleBytes, 2) & " GB"
                Case 1048576 To 1073741823
                    DoubleBytes = CDbl(bytes / 1048576) 'MB
                    Return FormatNumber(DoubleBytes, 2) & " MB"
                Case 1024 To 1048575
                    DoubleBytes = CDbl(bytes / 1024) 'KB
                    Return FormatNumber(DoubleBytes, 2) & " KB"
                Case 0 To 1023
                    DoubleBytes = bytes ' bytes
                    Return FormatNumber(DoubleBytes, 2) & " B"
                Case Else
                    Return ""
            End Select
        Catch
            Return ""
        End Try
    End Function
#End Region

#Region "Installation"
    Private Sub bgw_install_DoWork(sender As Object, e As DoWorkEventArgs) Handles bgw_install.DoWork
        bgw_install.ReportProgress(-1)
        cu.ExtractAllAsync(path & "\Data.zip", txt_s1_omsipath.Text)
        My.Computer.FileSystem.WriteAllText(txt_s1_omsipath.Text & "\maps\" & My.Resources.MapName & "\TTData\62_NBL_ZOB.ttp.old", txt_s1_key.Text & vbNewLine & lbl_user.Text, False)
        bgw_install.ReportProgress(-2)
        installhof(path & "\" & My.Resources.MapName & ".hof", txt_s1_omsipath.Text)
        bgw_install.ReportProgress(-3)
        Dim aiunzip As New ClassUnzip
        My.Computer.FileSystem.CreateDirectory(path & "\AILists\")
        aiunzip.ExtractAllAsync(path & "\ailists.zip", path & "\AILists\")
        bgw_install.ReportProgress(-4)
    End Sub

    Private Sub bgw_install_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles bgw_install.ProgressChanged
        If e.ProgressPercentage = -1 Then
            lbl_s4_progress.Text = "Installiere Karte ..."
        ElseIf e.ProgressPercentage = -2
            lbl_s4_progress.Text = "Installiere Hof-Dateien ..."
        ElseIf e.ProgressPercentage = -3
            lbl_s4_progress.Text = "Entpacke AI-Listen ..."
        ElseIf e.ProgressPercentage = -4
            changeTab(tp_5)
            bgw_loadmap.RunWorkerAsync()
        End If
    End Sub

    Private Sub cu_ProgressChanged(actprogress As Integer, overall As Integer, path As String) Handles cu.ProgressChanged
        pb_s4_progress.Maximum = overall
        pb_s4_progress.Value = actprogress
        lbl_s4_progress.Text = "Datei " & actprogress & " von " & overall & ": " & path
        Application.DoEvents()
    End Sub

    Private Sub cu_UnzipFinished(extractCount As Integer, errors As Integer) Handles cu.UnzipFinished
        If errors = 0 Then
        Else
            'MsgBox("Es ist zu Fehlern gekommen. Möglicherweise wurde die Karte nicht vollständig installiert.")
        End If
    End Sub
    Sub installhof(ByVal hofpath As String, ByVal omsipath As String)
        Dim pathsToBusses As New List(Of String)
        Dim hoffiles = My.Computer.FileSystem.GetFiles(omsipath & "\Vehicles\", FileIO.SearchOption.SearchAllSubDirectories, "*.hof")
        For Each file As String In hoffiles
            Dim folder As String = file.Replace(IO.Path.GetFileName(file), "")
            Dim vorhanden As Boolean = False
            For Each item As String In pathsToBusses
                If item = folder Then
                    vorhanden = True
                    Exit For
                End If
            Next
            If vorhanden = False Then
                pathsToBusses.Add(folder)
            End If
        Next
        For Each item As String In pathsToBusses
            My.Computer.FileSystem.CopyFile(hofpath, item & "\" & My.Resources.MapName & ".hof", True)
        Next
    End Sub

#End Region

    Private Sub cmd_s2_folder_Click_1(sender As Object, e As EventArgs) Handles cmd_s1_folder.Click
        Dim fbd As New FolderBrowserDialog
        With fbd
            .SelectedPath = txt_s1_omsipath.Text
            .Description = "OMSI-Verzeichnis auswählen"
            .ShowNewFolderButton = True
            If .ShowDialog = DialogResult.OK Then
                txt_s1_omsipath.Text = .SelectedPath
            End If
        End With
    End Sub

    Private Sub txt_s1_omsipath_TextChanged() Handles txt_s1_omsipath.TextChanged, txt_s1_key.TextChanged
        If My.Computer.FileSystem.FileExists(txt_s1_omsipath.Text & "\OMSI.exe") Then
            lbl_s1_omsi.BackColor = Color.White
            If txt_s1_key.Text = "" Then
                cmd_s1_weiter.Enabled = False
                cmd_s1_weiter.Style = MetroSuite.Design.Style.Dark
                lbl_s1_key.BackColor = Color.IndianRed
            Else
                cmd_s1_weiter.Enabled = True
                cmd_s1_weiter.Style = MetroSuite.Design.Style.Light
                lbl_s1_key.BackColor = Color.White
            End If
        Else
            cmd_s1_weiter.Enabled = False
            cmd_s1_weiter.Style = MetroSuite.Design.Style.Dark
            lbl_s1_omsi.BackColor = Color.IndianRed
            If txt_s1_key.Text = "" Then
                lbl_s1_key.BackColor = Color.IndianRed
            Else
                lbl_s1_key.BackColor = Color.White
            End If
        End If
    End Sub

    Dim path As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) & "\OMSI-Map\"

    Private Sub cmd_s2_weiter_Click(sender As Object, e As EventArgs) Handles cmd_s2_weiter.Click
        client.DownloadFileAsync(New Uri(My.Resources.URL_data), path & "\Data.zip")
        changeTab(tp_3)
    End Sub

    Private Sub cmd_s2_zurück_Click(sender As Object, e As EventArgs) Handles cmd_s2_zurück.Click
        End
    End Sub
#Region "Check"
    Dim objects As New List(Of String)
    Dim splines As New List(Of String)
    Dim textures As New List(Of String)

    Private Sub bgw_loadmap_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bgw_loadmap.DoWork
        Dim objects As New List(Of String)
        Dim splines As New List(Of String)
        Dim textures As New List(Of String)
        If My.Computer.FileSystem.FileExists(txt_s1_omsipath.Text & "\Vehicles\HH109_Stadtgelenkbus2012_HHA\HHStadtgelenkbus2012_parked.sco") Then
        Else
            My.Computer.FileSystem.WriteAllText(txt_s1_omsipath.Text & "\Vehicles\HH109_Stadtgelenkbus2012_HHA\HHStadtgelenkbus2012_parked.sco", "", False)
        End If
        Dim mapdata As ReadOnlyCollection(Of String) = My.Computer.FileSystem.GetFiles(txt_s1_omsipath.Text & "\Maps\" & My.Resources.MapName, FileIO.SearchOption.SearchTopLevelOnly, "*.map")
        bgw_loadmap.ReportProgress(0, mapdata.Count + 2)
        Dim count As Integer = 0
        Dim filedata As String()
        Dim i As Integer = 0
        For Each file As String In mapdata
            filedata = My.Computer.FileSystem.ReadAllText(file, System.Text.Encoding.GetEncoding(1250)).Split(vbCrLf)
            i = 0
            Do
                If filedata(i).Trim.Contains("[spline]") Then
                    Dim data As String = filedata(i + 2).Trim
                    Dim found As Boolean = False
                    For Each knownItem As String In splines
                        If knownItem = data Then
                            found = True
                            Exit For
                        End If
                    Next
                    If found = False Then
                        splines.Add(data)
                    End If
                ElseIf filedata(i).Trim.Contains("[object]")
                    Dim data As String = filedata(i + 2).Trim
                    Dim found As Boolean = False
                    For Each knownItem As String In objects
                        If knownItem = data Then
                            found = True
                            Exit For
                        End If
                    Next
                    If found = False Then
                        objects.Add(data)
                    End If
                End If
                i += 1
            Loop While i < filedata.Length
            count += 1
            bgw_loadmap.ReportProgress(count, mapdata.Count + 2)
        Next

        'Textures
        filedata = My.Computer.FileSystem.ReadAllText(txt_s1_omsipath.Text & "\Maps\" & My.Resources.MapName & "\global.cfg", System.Text.Encoding.GetEncoding(1250)).Split(vbCrLf)
        i = 0
        Do
            If filedata(i).Trim.Contains("[groundtex]") Then
                textures.Add(filedata(i + 1).Trim)
                textures.Add(filedata(i + 2).Trim)
            End If
            i += 1
        Loop While i < filedata.Length
        count += 1
        bgw_loadmap.ReportProgress(count, mapdata.Count + 2)

        bgw_loadmap.ReportProgress(-1, objects)
        bgw_loadmap.ReportProgress(-2, splines)
        bgw_loadmap.ReportProgress(-4, textures)
    End Sub

    Private Sub bgw_loadmap_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles bgw_loadmap.ProgressChanged
        If e.ProgressPercentage = -1 Then
            objects = e.UserState
        ElseIf e.ProgressPercentage = -2
            splines = e.UserState
        ElseIf e.ProgressPercentage = -4
            textures = e.UserState
            fillListBoxes()
        Else
            pb_s5_progress.Value = e.ProgressPercentage
            Try : pb_s5_progress.Maximum = e.UserState : Catch : End Try
        End If
    End Sub

    Sub fillListBoxes()
        lb_objects.Items.Clear()
        lb_splines.Items.Clear()
        lb_textures.Items.Clear()
        For Each item As String In objects
            If My.Computer.FileSystem.FileExists(IO.Path.Combine(txt_s1_omsipath.Text, item)) = False Then
                lb_objects.Items.Add(item)
            End If
        Next
        For Each item As String In splines
            If My.Computer.FileSystem.FileExists(IO.Path.Combine(txt_s1_omsipath.Text, item)) = False Then
                lb_splines.Items.Add(item)
            End If
        Next
        For Each item As String In textures
            If My.Computer.FileSystem.FileExists(IO.Path.Combine(txt_s1_omsipath.Text, item)) = False Then
                lb_textures.Items.Add(item)
            End If
        Next

        If lb_objects.Items.Count = 0 And lb_splines.Items.Count = 0 And lb_textures.Items.Count = 0 Then
            cmd_s5_weiter.Enabled = True
            cmd_s5_weiter.Style = MetroSuite.Design.Style.Light
            lbl_s5_caption.Text = "Alle benötigten Addons sind installiert!"
            lbl_s5_caption.BackColor = Color.White
            cmd_s5_refresh.Visible = False
        Else
            cmd_s5_weiter.Enabled = False
            cmd_s5_weiter.Style = MetroSuite.Design.Style.Dark
            lbl_s5_caption.Text = "Bitte installieren sie die unten aufgeführten Dateien!"
            lbl_s5_caption.BackColor = Color.IndianRed
            cmd_s5_refresh.Visible = True
        End If
    End Sub

    Private Sub cmd_s5_refresh_Click(sender As Object, e As EventArgs) Handles cmd_s5_refresh.Click
        bgw_loadmap.RunWorkerAsync()
    End Sub
#End Region
#Region "AI-Listen"
    Private Sub cmd_s5_weiter_Click(sender As Object, e As EventArgs) Handles cmd_s5_weiter.Click
        For Each item As String In My.Computer.FileSystem.GetFiles(path & "\AILists\", FileIO.SearchOption.SearchAllSubDirectories, "*.cfg")
            cmb_s6_ailists.Items.Add(item.Replace(path & "AILists\", "").Replace(".cfg", ""))
        Next
        changeTab(tp_6)
        cmb_s6_ailists.SelectedIndex = 0
    End Sub

    Private Sub cmb_s6_ailists_TextChanged(sender As Object, e As EventArgs) Handles cmb_s6_ailists.TextChanged
        lv_ailist.Groups.Clear()
        lv_ailist.Items.Clear()


        Dim filedata As String()
        Dim i As Integer = 0
        filedata = My.Computer.FileSystem.ReadAllText(path & "AILists\" & cmb_s6_ailists.Text & ".cfg", System.Text.Encoding.GetEncoding(1250)).Split(vbCrLf)
        i = 0
        Dim lvg As ListViewGroup
        Do
            If filedata(i).Trim.Contains("[aigroup_2]") Then
                lvg = New ListViewGroup(filedata(i + 1))
                lv_ailist.Groups.Add(lvg)
                i += 3
                Do
                    Try
                        lv_ailist.Items.Add(New ListViewItem(filedata(i).Trim.Split(vbTab)(0), lvg))
                    Catch : End Try
                    i += 1
                Loop Until filedata(i).Trim.Contains("[end]")
            ElseIf filedata(i).Trim.Contains("[aigroup_depot]")
                lvg = New ListViewGroup(filedata(i + 1))
                lv_ailist.Groups.Add(lvg)
            ElseIf filedata(i).Trim.Contains("[aigroup_depot_typgroup_2]") Then
                Try
                    lv_ailist.Items.Add(New ListViewItem(filedata(i + 1).Trim.Split(vbTab)(0), lvg))
                Catch : End Try
            ElseIf filedata(i).Trim.Contains("[ailist]")
                Dim countdown As Integer = filedata(i + 3)
                i += 4
                Do
                    Try
                        lv_ailist.Items.Add(New ListViewItem(filedata(i).Trim.Split(vbTab)(0)))
                    Catch : End Try
                    i += 1
                    countdown -= 1
                Loop Until countdown = 0
            End If
            i += 1
        Loop While i < filedata.Length
    End Sub

    Private Sub cmd_s6_weiter_Click(sender As Object, e As EventArgs) Handles cmd_s6_weiter.Click
        My.Computer.FileSystem.CopyDirectory(path & "\AILists\", txt_s1_omsipath.Text & "\Maps\" & My.Resources.MapName & "\AILists\", True)
        My.Computer.FileSystem.CopyFile(path & "\AILists\" & cmb_s6_ailists.Text & ".cfg", txt_s1_omsipath.Text & "\Maps\" & My.Resources.MapName & "\ailists.cfg", True)
        changeTab(tp_7)
    End Sub

    Private Sub cmd_s7_fin_Click(sender As Object, e As EventArgs) Handles cmd_s7_fin.Click
        If sw_s7_start.Status = MetroSuite.MetroSwitch.CurrentStatus.Left Then
            Process.Start(txt_s1_omsipath.Text & "\Omsi.exe")
        End If
        pb_s3.Image.Dispose()
        pb_s4.Image.Dispose()
        CloseDown.Show()
        Me.Close()
    End Sub

    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        pb_s3.Image.Dispose()
        pb_s4.Image.Dispose()
        CloseDown.Show()
        Me.Close()
    End Sub
#End Region
End Class