# Änderungsziel vs. 1: Funktion bei Klick auf "Auswählen" und "Zurück" auslagern
# Known problem: Zugriffsversuch auf einen Ordner, für den der Nutzer keine Freigabe hat. Aktuell kein Lösungsansatz bekannt.
# Todo: siehe Zettel!

Function Main
{

Write-Host "Programmstart"

$StartPfad = ""

$PfadUrsprungsdatei = GuiTxtWaehlen $StartPfad
Write-Host "Pfad Ursprungsdatei: " $PfadUrsprungsdatei


# Testen, ob übergebener Pfad gültig ist? Könnte ungültig sein, wenn in PfadFeld unsinn steht und das Fenster via x geschlossen wird
$PfadUrsprungsdateiMod = Split-Path $PfadUrsprungsdatei
$PfadZielDateien = GuiVerzeichnisWaehlen $PfadUrsprungsdateiMod

Write-Host "Dateirückgabe in Main(2): " $PfadZielDateien

GUI für Fortschrittsanzeige
GuiFortschrittsAnzeige $PfadUrsprungsdatei

# Ab hier...........................................................................................................................
Write-Host "Ausgabe nach Fortschrittsanzeige"

$PfadDateiEA = ExcelDateiNameErstellen "EA" $PfadUrsprungsdatei $PfadZielDateien
$PfadDateiDIDQ = ExcelDateiNameErstellen "DIDQ" $PfadUrsprungsdatei $PfadZielDateien

#$ListeErledigteAufgaben.Items.Add("Neue Dateinamenerstellen")
#$TextfeldAktuelleAufgabe.Text = "EA-Datei erstellen"

#Write-Host "Dateiname EA: " $PfadDateiEA
#Write-Host "Dateiname DIDQ: " $PfadDateiDIDQ
ExcelDateiErstellen $PfadDateiEA
ExcelDateiErstellen $PfadDateiDIDQ

$AlleGleichenEA = ExcelDateiBeschreiben $PfadUrsprungsdatei "E" "A" $PfadDateiEA
$AlleGleichenDIDQ = ExcelDateiBeschreiben $PfadUrsprungsdatei "DI" "DQ" $PfadDateiDIDQ
#Write-Host "Gleiche EA nach Rückgabe: " $AlleGleichenEA
$GleicheEingaenge = $AlleGleichenEA[0]
$GleicheAusgaenge = $AlleGleichenEA[1]

Write-Host "Gleiche Eingänge: " $GleicheEingaenge
Write-Host "Gleiche Ausgänge: " $GleicheAusgaenge
# ......................bis hier alles in das guiFortschrittsanzeige verschieben und in die Funktionen die Updates einbauen.................

#Todo: Nur öffnen, wenn es weder gleiche Eingänge, noch gleiche Ausgänge gibt?
GuiGleicheAnzeigen $GleicheEingaenge $GleicheAusgaenge

}


Function GuiTxtWaehlen ($StartPfad)
{
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

# Eigenschaften Fenster
$Fenster = New-Object System.Windows.Forms.Form
$Fenster.Size = New-Object System.Drawing.Size(900,600) #Breite, Höhe
$Fenster.StartPosition = "CenterScreen"
$Fenster.KeyPreview = $true # was macht das?
$Fenster.MaximumSize = $Fenster.Size # legt fest, dass Größe des Fensters nicht verändert werden kann
$Fenster.MinimumSize = $Fenster.Size

# PfadFeld
$PfadFeld = New-Object System.Windows.Forms.TextBox
$PfadFeld.Location = New-Object System.Drawing.Size(10,10)
$PfadFeld.Size = New-Object System.Drawing.Size(860,20)
$PfadFeld.Add_KeyDown({
    # Reaktion bei gedrückter Taste
    $Taste = $_.KeyCode
    TXTTastenReaktionPfadFeld $Taste
})
$Fenster.Controls.Add($PfadFeld)

# ListeOrdnernamen
$ListeOrdnernamen = New-Object System.Windows.Forms.ListBox
$ListeOrdnernamen.Location = New-Object System.Drawing.Size(10,40)
$ListeOrdnernamen.Size = New-Object System.Drawing.Size(860,20)
$ListeOrdnernamen.Height = 450
$ListeOrdnernamen.Font = New-Object System.Drawing.Font("Arial",12,[System.Drawing.FontStyle]::Regular)
$ListeOrdnernamen.Add_DoubleClick({
    # Variablen bestimmen zur Übergabe
    $Auswahl = $ListeOrdnernamen.SelectedItem
    $Pfad = $PfadFeld.Text
    # Write-Host "Gewählter Ordner/ Datei: " $Auswahl
    # Write-Host "Vorheriger Pfad: " $Pfad

    # Pfad aktualisieren
    TXTVerzeichnisAuswaehlen $Pfad $Auswahl
})
$ListeOrdnernamen.Add_KeyDown({
    # Reaktion bei gedrückter Taste
    $Taste = $_.KeyCode
    TXTTastenReaktionListeOrdnernamen $Taste
})
$Fenster.Controls.Add($ListeOrdnernamen)

<#
# Beispiel Textfeld
$Textfeld1 = New-Object System.Windows.Forms.Label
$Textfeld1.Location = New-Object System.Drawing.Size(7,500)
$Textfeld1.Size = New-Object System.Drawing.Size(130,15)
$Textfeld1.Text = "Beispiel Text"
$Fenster.Controls.Add($Textfeld1)
#>

# ZurückButton
$ZurückButton = New-Object System.Windows.Forms.Button
$ZurückButton.Location = New-Object System.Drawing.Size(10,500)
$ZurückButton.Size = New-Object System.Drawing.Size(100,30)
$ZurückButton.Text = "Zurück"
$ZurückButton.Add_Click({
    # Write-Host "Pfad ausgabe: " $PfadFeld.Text
    $Pfad = $PfadFeld.Text

    #Pfad aktualisieren
    TXTVerzeichnisZurueck $Pfad
})
$ZurückButton.Add_KeyDown({
    # Reaktion bei gedrückter Taste
    $Taste = $_.KeyCode
    TXTTastenReaktionButtons $Taste
})
$Fenster.Controls.Add($ZurückButton)

# AuswählenButton
$AuswählenButton = New-Object System.Windows.Forms.Button
$AuswählenButton.Location = New-Object System.Drawing.Size(750,500)
$AuswählenButton.Size = New-Object System.Drawing.Size(100,30)
$AuswählenButton.Text = "Auswählen"
$AuswählenButton.Add_Click({
    # Variablen bestimmen zur Übergabe
    $Auswahl = $ListeOrdnernamen.SelectedItem
    # Falls nicht aktiv ein Eintrag gewählt wurde, in den obersten navigieren
    if ($($Auswahl.length -eq 0))
    {
        $Auswahl = $ListeOrdnernamen.Items[0]
    }
    $Pfad = $PfadFeld.Text
    # Write-Host "Gewählter Ordner/ Datei: " $Auswahl
    # Write-Host "Vorheriger Pfad: " $Pfad

    # Pfad aktualisieren
    TXTVerzeichnisAuswaehlen $Pfad $Auswahl
})
$AuswählenButton.Add_KeyDown({
    # Reaktion bei gedrückter Taste
    $Taste = $_.KeyCode
    TXTTastenReaktionButtons $Taste
})
$Fenster.Controls.Add($AuswählenButton)

# Dieser Funktionsaufruf zerstört die Rückgabe, wenn er keiner Variable zugewiesen wird
$A = TXTAnzeigeAktualisieren $StartPfad

$Fenster.Add_Shown({$Fenster.Activate()})
[void]$Fenster.ShowDialog()

$Rueckgabe = $PfadFeld.Text
Write-Host "Rückgabe: " $Rueckgabe
return $Rueckgabe
}

#--------------------------------------------------------- E N D E   G U I  txtWaehlen ----------------------------------------------------------------------

#------------------- Funktionen nur für das txt-GUI --------------------------

# Bekommt Pfad, stellt fest ob Laufwerke oder Ordner angezeigt werden müssen und aktualisiert entsprechend alles
# Für Laufwerke muss $Pfad = "" sein
Function TXTAnzeigeAktualisieren ($Pfad)
{
# Write-Host "Übergebener Pfad: " $Pfad

# Sicherstellen, dass es das Verzeichnis gibt
if ($($Pfad -eq "") -or $(PfadExistiert $Pfad))
{
    # Feststellen, ob Ordner oder Laufwerke angezeigt werden müssen
    if ($Pfad.Length -ne "")
    {
        # Es handelt sich um Ordner
        $Optionen = TXTOptionen $Pfad
        $Fenster.Text = $(Split-Path $Pfad -Leaf)
    }
    elseif ($Pfad.Length -eq "")
    {
        # Es handelt sich um Laufwerke
        $Optionen = LaufwerkeFinden
        $Pfad = ""
        $Fenster.Text = "Laufwerke"
    }
    else 
    {
        Write-Host "Fehler bei Anzeige aktualisieren"
        # Fehler(?)
    }
    $PfadFeld.Text = $Pfad
    $ListeOrdnernamen.Items.Clear()
    foreach ($Option in $Optionen)
    {
        if ($Option.Length -gt 0)
        {
            $ListeOrdnernamen.Items.Add($Option)
        }
    }
}
else
{
    TXTAnzeigeAktualisieren ""
}
return
}

Function TXTVerzeichnisAuswaehlen ($Pfad, $Auswahl)
{
if ($Pfad.length -gt 0)
{
    $Pfad = Join-Path -Path $Pfad -ChildPath $Auswahl -Resolve
}
else
{
    $Pfad = $Auswahl
}

#Falls nicht aktiv ein Eintrag ausgewählt wurde, den obersten wählen
if ($Auswahl.length -eq 0)
{
    $Auswahl = $ListeOrdnernamen.Items[0]
}

# Erkennen, ob *.txt-Datei gewählt wurde -> ggf. Auswahl abgeschlossen
if ($($Auswahl -match ".txt"))
{
    # Write-Host ".txt-Datei ausgewählt, Pfad: " $Pfad
    # Write-Host "Dateityp: " $Pfad.GetType()
    $Fenster.Dispose()
    # Ist zwar sachlich gesehen unsinn, aber sonst funktioniert Return in der GUI nicht
    $PfadFeld.Text = $Pfad
    return
}

TXTAnzeigeAktualisieren $Pfad

return
}

Function TXTVerzeichnisZurueck ($Pfad)
{
if ($Pfad.Length -gt 3)
{
    # Weiter mit Ordnern
    # Write-Host "Ordner anzeigen"
    $Pfad = Split-Path $Pfad
}
elseif ($Pfad.Length -le 3)
{
    # Weiter mit Laufwerken
    # Write-Host "Laufwerke anzeigen"
    $Pfad = ""
}
else
{
    Write-Host "Fehler bei Verzeichnis zurück"
    # Fehler/ Nichts tun?
    # Ermitteln: wann tritt dieser Fall ein?
}
TXTAnzeigeAktualisieren $Pfad
return
}

Function TXTTastenReaktionPfadFeld($Taste)
{
# Write-Host "Übergebene Taste: " $Taste
switch ($Taste){
    "Return" {
        # Write-Host "Enter gedrückt"
        $Pfad = $PfadFeld.Text
        # Write-Host "Pfad: " $Pfad
        
        TXTReaktionReturn $Pfad
    }
    default {
        # Write-Host "Gedrückte Taste: " $Taste
    }
}
return
}

Function TXTTastenReaktionListeOrdnernamen($Taste)
{
# Write-Host "Übergebene Taste: " $Taste
switch ($Taste){
    "Return" {
        # Write-Host "Enter gedrückt"
        $Auswahl = $ListeOrdnernamen.SelectedItem
        if ($($Auswahl.Length -eq 0))
        {
            $Auswahl = $ListeOrdnernamen.Items[0]
        }
        $Pfad = $PfadFeld.Text
        # Write-Host "Auswahl: " $Auswahl
        # Write-Host "Pfad: " $Pfad
        
        TXTVerzeichnisAuswaehlen $Pfad $Auswahl
    }
    "Back" {
        # Write-Host "Back gedrückt"
        $Pfad = $PfadFeld.Text
        # Write-Host "Pfad: " $Pfad

        # Pfad aktualisieren
        TXTVerzeichnisZurueck $Pfad
    }
    default {
        # Write-Host "Gedrückte Taste: " $Taste
    }
}
return
}

Function TXTTastenReaktionButtons($Taste)
{
# Write-Host "Übergebene Taste: " $Taste
switch ($Taste){
    "Back" {
        # Write-Host "Back gedrückt"
        $Pfad = $PfadFeld.Text
        # Write-Host "Pfad: " $Pfad

        # Pfad aktualisieren
        TXTVerzeichnisZurueck $Pfad
    }
    default {
        # Write-Host "Gedrückte Taste: " $Taste
    }
}
return
}

Function TXTOptionen($Pfad)
{
# Unterordner und .txt-Dateien finden
# Typzuweisung nötig, da aus unbekanntem Grund sonst Unterordner eines Ordners, der mit "_" beginnt, nicht gefunden werden können
[System.Object[]]$UnterOrdner = UnterOrdnerFinden $Pfad
$TxtDateien = TxtDateienFinden $Pfad

#Gibt aktuell auch Index und Typ (System.IO.DirectoryInfo bzw. System.String) zurück
$Optionen = $UnterOrdner + $TxtDateien

return $Optionen
}

Function TXTReaktionReturn ($Pfad)
{
    if (PfadExistiert $Pfad)
    {
        # Gültiger Pfad oder .txt-Datei
        $PfadEnde = $(Split-Path $Pfad -Leaf)
        if ($($PfadEnde -match ".txt"))
        {
            $Fenster.Dispose()
            # Ist zwar sachlich gesehen unsinn, aber sonst funktioniert Return in der GUI nicht richtig
            $PfadFeld.Text = $Pfad
            return
        }
        else
        {
            TXTAnzeigeAktualisieren $Pfad
        }
    }
    else
    {
        # Laufwerke aktualisieren oder ungültiger Pfad
        TXTAnzeigeAktualisieren ""
    }
    return
}

Function GuiVerzeichnisWaehlen ($StartPfad)
{
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

# Eigenschaften Fenster
$Fenster = New-Object System.Windows.Forms.Form
$Fenster.Size = New-Object System.Drawing.Size(900,600) #Breite, Höhe
$Fenster.StartPosition = "CenterScreen"
$Fenster.KeyPreview = $true # was macht das?
$Fenster.MaximumSize = $Fenster.Size # legt fest, dass Größe des Fensters nicht verändert werden kann
$Fenster.MinimumSize = $Fenster.Size

# PfadFeld
$PfadFeld = New-Object System.Windows.Forms.TextBox
$PfadFeld.Location = New-Object System.Drawing.Size(10,10)
$PfadFeld.Size = New-Object System.Drawing.Size(860,20)
$PfadFeld.Add_KeyDown({
    # Reaktion bei gedrückter Taste
    $Taste = $_.KeyCode
    VERTastenReaktionPfadFeld $Taste
})
$Fenster.Controls.Add($PfadFeld)

# ListeOrdnernamen
$ListeOrdnernamen = New-Object System.Windows.Forms.ListBox
$ListeOrdnernamen.Location = New-Object System.Drawing.Size(10,40)
$ListeOrdnernamen.Size = New-Object System.Drawing.Size(860,20)
$ListeOrdnernamen.Height = 450
$ListeOrdnernamen.Font = New-Object System.Drawing.Font("Arial",12,[System.Drawing.FontStyle]::Regular)
$ListeOrdnernamen.Add_DoubleClick({
    # Variablen bestimmen zur Übergabe
    $Auswahl = $ListeOrdnernamen.SelectedItem
    $Pfad = $PfadFeld.Text
    # Write-Host "Gewählter Ordner/ Datei: " $Auswahl
    # Write-Host "Vorheriger Pfad: " $Pfad

    # Pfad aktualisieren
    VERVerzeichnisAuswaehlen $Pfad $Auswahl
})
$ListeOrdnernamen.Add_KeyDown({
    # Reaktion bei gedrückter Taste
    $Taste = $_.KeyCode
    VERTastenReaktionListeOrdnernamen $Taste
})
$Fenster.Controls.Add($ListeOrdnernamen)

<#
# Beispiel Textfeld
$Textfeld1 = New-Object System.Windows.Forms.Label
$Textfeld1.Location = New-Object System.Drawing.Size(7,500)
$Textfeld1.Size = New-Object System.Drawing.Size(130,15)
$Textfeld1.Text = "Beispiel Text"
$Fenster.Controls.Add($Textfeld1)
#>

# ZurückButton
$ZurückButton = New-Object System.Windows.Forms.Button
$ZurückButton.Location = New-Object System.Drawing.Size(10,500)
$ZurückButton.Size = New-Object System.Drawing.Size(100,30)
$ZurückButton.Text = "Zurück"
$ZurückButton.Add_Click({
    # Write-Host "Pfad ausgabe: " $PfadFeld.Text
    $Pfad = $PfadFeld.Text

    #Pfad aktualisieren
    VERVerzeichnisZurueck $Pfad
})
$ZurückButton.Add_KeyDown({
    # Reaktion bei gedrückter Taste
    $Taste = $_.KeyCode
    VERTastenReaktionButtons $Taste
})
$Fenster.Controls.Add($ZurückButton)

# AuswählenButton
$AuswählenButton = New-Object System.Windows.Forms.Button
$AuswählenButton.Location = New-Object System.Drawing.Size(630,500)
$AuswählenButton.Size = New-Object System.Drawing.Size(100,30)
$AuswählenButton.Text = "Auswählen"
$AuswählenButton.Add_Click({
    # Variablen bestimmen zur Übergabe
    $Auswahl = $ListeOrdnernamen.SelectedItem
    # Falls nicht aktiv ein Eintrag gewählt wurde, in den obersten navigieren
    if ($($Auswahl.length -eq 0))
    {
        $Auswahl = $ListeOrdnernamen.Items[0]
    }
    $Pfad = $PfadFeld.Text
    # Write-Host "Gewählter Ordner/ Datei: " $Auswahl
    # Write-Host "Vorheriger Pfad: " $Pfad

    if ($($ListeOrdnernamen.Items[0] -eq ""))
    {
        VERAuswahlBestaetigt $Pfad $Auswahl
    }
    else
    {
        # Pfad aktualisieren
        VERVerzeichnisAuswaehlen $Pfad $Auswahl
    }
})
$AuswählenButton.Add_KeyDown({
    # Reaktion bei gedrückter Taste
    $Taste = $_.KeyCode
    VERTastenReaktionButtons $Taste
})
$Fenster.Controls.Add($AuswählenButton)

# BestätigenButton
$BestätigenButton = New-Object System.Windows.Forms.Button
$BestätigenButton.Location = New-Object System.Drawing.Size(750,500)
$BestätigenButton.Size = New-Object System.Drawing.Size(100,30)
$BestätigenButton.Text = "Bestätigen"
$BestätigenButton.Add_Click({
    $Auswahl = $ListeOrdnernamen.SelectedItem
    # Falls nicht aktiv ein Eintrag gewählt wurde, in den obersten navigieren
    if ($($Auswahl.length -eq 0))
    {
        $Auswahl = $ListeOrdnernamen.Items[0]
    }
    $Pfad = $PfadFeld.Text

    VERAuswahlBestaetigt $Pfad $Auswahl
})
$BestätigenButton.Add_KeyDown({
    # Reaktion bei gedrückter Taste
    $Taste = $_.KeyCode
    VERTastenReaktionButtons $Taste
})
$Fenster.Controls.Add($BestätigenButton)


# Dieser Funktionsaufruf zerstört die Rückgabe, wenn er keiner Variable zugewiesen wird
$A = VERAnzeigeAktualisieren $StartPfad

$Fenster.Add_Shown({$Fenster.Activate()})
[void]$Fenster.ShowDialog()

$Rueckgabe2 = $PfadFeld.Text
Write-Host "Rückgabe: " $Rueckgabe2
return $Rueckgabe2
}

#--------------------------------------------------------- E N D E   G U I  VerzeichnsWaehlen ----------------------------------------------------------------------

#------------------- Funktionen nur für das VerzeichnisWaehlen-GUI --------------------------

# Bekommt Pfad, stellt fest ob Laufwerke oder Ordner angezeigt werden müssen und aktualisiert entsprechend alles
# Für Laufwerke muss $Pfad = "" sein
Function VERAnzeigeAktualisieren ($Pfad)
{
# Write-Host "Übergebener Pfad: " $Pfad

# Sicherstellen, dass es das Verzeichnis gibt
if ($($Pfad -eq "") -or $(PfadExistiert $Pfad))
{
    # Feststellen, ob Ordner oder Laufwerke angezeigt werden müssen
    if ($Pfad.Length -ne "")
    {
        # Es handelt sich um Ordner
        $Optionen = VEROptionen $Pfad
        $Fenster.Text = $(Split-Path $Pfad -Leaf)
    }
    elseif ($Pfad.Length -eq "")
    {
        # Es handelt sich um Laufwerke
        $Optionen = LaufwerkeFinden
        $Pfad = ""
        $Fenster.Text = "Laufwerke"
    }
    else 
    {
        Write-Host "Fehler bei Anzeige aktualisieren"
        # Fehler(?)
    }
    $PfadFeld.Text = $Pfad
    $ListeOrdnernamen.Items.Clear()
    foreach ($Option in $Optionen)
    {
        if ($Option.Length -gt 0)
        {
            $ListeOrdnernamen.Items.Add($Option)
        }
    }
}
else
{
    VERAnzeigeAktualisieren ""
}
return
}


Function VERVerzeichnisAuswaehlen ($Pfad, $Auswahl)
{
#Falls nicht aktiv ein Eintrag ausgewählt wurde, den obersten wählen
if ($Auswahl.length -eq 0)
{
    $Auswahl = $ListeOrdnernamen.Items[0]
}

if ($Pfad.length -gt 0)
{
    $Pfad = Join-Path -Path $Pfad -ChildPath $Auswahl -Resolve
}
else
{
    $Pfad = $Auswahl
}

VERAnzeigeAktualisieren $Pfad
return
}

Function VERVerzeichnisZurueck ($Pfad)
{
if ($Pfad.Length -gt 3)
{
    # Weiter mit Ordnern
    # Write-Host "Ordner anzeigen"
    $Pfad = Split-Path $Pfad
}
elseif ($Pfad.Length -le 3)
{
    # Weiter mit Laufwerken
    # Write-Host "Laufwerke anzeigen"
    $Pfad = ""
}
else
{
    Write-Host "Fehler bei Verzeichnis zurück"
    # Fehler/ Nichts tun?
    # Ermitteln: wann tritt dieser Fall ein?
}
VERAnzeigeAktualisieren $Pfad
return
}

Function VERTastenReaktionPfadFeld($Taste)
{
# Write-Host "Übergebene Taste: " $Taste
switch ($Taste){
    "Return" {
        # Write-Host "Enter gedrückt"
        $Pfad = $PfadFeld.Text
        # Write-Host "Pfad: " $Pfad
        # Es muss nicht überprüft werden, ob es das Verzeichnis gibt, da dies auch in VERAnzeigeAktualisieren gemacht wird
        VERAnzeigeAktualisieren $Pfad
    }
    "ShiftKey" {
        $Pfad = $PfadFeld.Text
        $Auswahl = $ListeOrdnernamen.SelectedItem
        # Falls nicht aktiv ein Eintrag gewählt wurde, in den obersten navigieren
        if ($($Auswahl.length -eq 0))
        {
            $Auswahl = $ListeOrdnernamen.Items[0]
        }

        ReaktionShiftKey $Pfad $Auswahl 
    }
    default {
        # Write-Host "Gedrückte Taste: " $Taste
    }
}
return
}

Function VERTastenReaktionListeOrdnernamen($Taste)
{
# Write-Host "Übergebene Taste: " $Taste
switch ($Taste){
    "Return" {
        # Write-Host "Enter gedrückt"
        $Auswahl = $ListeOrdnernamen.SelectedItem
        if ($($Auswahl.Length -eq 0))
        {
            $Auswahl = $ListeOrdnernamen.Items[0]
        }
        $Pfad = $PfadFeld.Text
        # Write-Host "Auswahl: " $Auswahl
        # Write-Host "Pfad: " $Pfad
        
        VERVerzeichnisAuswaehlen $Pfad $Auswahl
    }
    "Back" {
        # Write-Host "Back gedrückt"
        $Pfad = $PfadFeld.Text
        # Write-Host "Pfad: " $Pfad

        # Pfad aktualisieren
        VERVerzeichnisZurueck $Pfad
    }
    "ShiftKey" {
        $Pfad = $PfadFeld.Text
        $Auswahl = $ListeOrdnernamen.SelectedItem
        # Falls nicht aktiv ein Eintrag gewählt wurde, in den obersten navigieren
        if ($($Auswahl.length -eq 0))
        {
            $Auswahl = $ListeOrdnernamen.Items[0]
        }
        
        ReaktionShiftKey $Pfad $Auswahl 
    }
    default {
        # Write-Host "Gedrückte Taste: " $Taste
    }
}
return
}

Function VERTastenReaktionButtons($Taste)
{
# Write-Host "Übergebene Taste: " $Taste
switch ($Taste){
    "Back" {
        # Write-Host "Back gedrückt"
        $Pfad = $PfadFeld.Text
        # Write-Host "Pfad: " $Pfad

        # Pfad aktualisieren
        VERVerzeichnisZurueck $Pfad
    }
    "ShiftKey" {
        $Pfad = $PfadFeld.Text
        $Auswahl = $ListeOrdnernamen.SelectedItem
        # Falls nicht aktiv ein Eintrag gewählt wurde, in den obersten navigieren
        if ($($Auswahl.length -eq 0))
        {
            $Auswahl = $ListeOrdnernamen.Items[0]
        }

        ReaktionShiftKey $Pfad $Auswahl  
    }
    default {
        # Write-Host "Gedrückte Taste: " $Taste
    }
}
return
}

Function VEROptionen($Pfad)
{
# Unterordner und .txt-Dateien finden
# Typzuweisung nötig, da aus unbekanntem Grund sonst Unterordner eines Ordners, der mit "_" beginnt, nicht gefunden werden können
[System.Object[]]$UnterOrdner = UnterOrdnerFinden $Pfad
# $TxtDateien = TxtDateienFinden $Pfad

#Gibt aktuell auch Index und Typ (System.IO.DirectoryInfo bzw. System.String) zurück
$Optionen = $UnterOrdner
return $Optionen
}

Function VERAuswahlBestaetigt($Pfad, $Auswahl)
{
$Pfad = Join-Path -Path $Pfad -ChildPath $Auswahl -Resolve

if (PfadExistiert $Pfad)
{
    Write-Host "Pfad zur Rückgabe: " $Pfad
    $Fenster.Dispose()
    $Pfadfeld.Text = $Pfad
    return
}
}

Function GuiFortschrittsAnzeige ($PfadUrsprungsdatei)
{
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

    # Eigenschaften Fenster
    $FortschrittFenster = New-Object System.Windows.Forms.Form
    $FortschrittFenster.Size = New-Object System.Drawing.Size(755,270) #Breite, Höhe
    $FortschrittFenster.StartPosition = "CenterScreen"
    $FortschrittFenster.KeyPreview = $true # was macht das?
    $FortschrittFenster.MaximumSize = $FortschrittFenster.Size # legt fest, dass Größe des Fensters nicht verändert werden kann
    $FortschrittFenster.MinimumSize = $FortschrittFenster.Size
    $FortschrittFenster.Text = "Fortschritt Dateikonvertierung"

    $Textfeld1 = New-Object System.Windows.Forms.Label
    $Textfeld1.Location = New-Object System.Drawing.Size(10,10)
    $Textfeld1.Size = New-Object System.Drawing.Size(200,20)
    $Textfeld1.Text = "Aktuelle Aufgabe"
    $FortschrittFenster.Controls.Add($Textfeld1)

    $Textfeld2 = New-Object System.Windows.Forms.Label
    $Textfeld2.Location = New-Object System.Drawing.Size(300,10)
    $Textfeld2.Size = New-Object System.Drawing.Size(430,20)
    $Textfeld2.Text = "Erledigte Aufgaben"
    $FortschrittFenster.Controls.Add($Textfeld2)

    $TextfeldAktuelleAufgabe = New-Object System.Windows.Forms.Label
    $TextfeldAktuelleAufgabe.Location = New-Object System.Drawing.Size(10,40)
    $TextfeldAktuelleAufgabe.Size = New-Object System.Drawing.Size(280,20)
    $TextfeldAktuelleAufgabe.Text = "Neue Dateinamen erstellen"
    $FortschrittFenster.Controls.Add($TextfeldAktuelleAufgabe)

    $ListeErledigteAufgaben = New-Object System.Windows.Forms.ListBox
    $ListeErledigteAufgaben.Location = New-Object System.Drawing.Size(300,40)
    $ListeErledigteAufgaben.Size = New-Object System.Drawing.Size(430,20)
    $ListeErledigteAufgaben.Height = 150
    $ListeErledigteAufgaben.Font = New-Object System.Drawing.Font("Arial",12,[System.Drawing.FontStyle]::Regular)
    $FortschrittFenster.Controls.Add($ListeErledigteAufgaben)

    $Textfeld3 = New-Object System.Windows.Forms.Label
    $Textfeld3.Location = New-Object System.Drawing.Size(10,100)
    $Textfeld3.Size = New-Object System.Drawing.Size(430,20)
    $Textfeld3.Text = "Gesamtfortschritt"
    $FortschrittFenster.Controls.Add($Textfeld3)

    $Fortschrittsbar = New-Object System.Windows.Forms.ProgressBar
    $Fortschrittsbar.Location = New-Object System.Drawing.Size(10,120)
    $Fortschrittsbar.Size = New-Object System.Drawing.Size(260,30)
    #$Fortschrittsbar.Name = "Fortschrittsanzeige"
    $Fortschrittsbar.Value = 0
    $FortschrittFenster.Controls.Add($Fortschrittsbar)

    $Textfeld4 = New-Object System.Windows.Forms.Label
    $Textfeld4.Location = New-Object System.Drawing.Size(10,170)
    $Textfeld4.Size = New-Object System.Drawing.Size(120,20)
    $Textfeld4.Text = "Bearbeitete Einträge:"
    $FortschrittFenster.Controls.Add($Textfeld4)

    $Textfeld5 = New-Object System.Windows.Forms.Label
    $Textfeld5.Location = New-Object System.Drawing.Size(10,200)
    $Textfeld5.Size = New-Object System.Drawing.Size(100,20)
    $Textfeld5.Text = "Gesamteinträge:"
    $FortschrittFenster.Controls.Add($Textfeld5)

    $TextfeldBearbeiteteEinträge = New-Object System.Windows.Forms.Label
    $TextfeldBearbeiteteEinträge.Location = New-Object System.Drawing.Size(140,170)
    $TextfeldBearbeiteteEinträge.Size = New-Object System.Drawing.Size(430,20)
    $TextfeldBearbeiteteEinträge.Text = "0"
    $FortschrittFenster.Controls.Add($TextfeldBearbeiteteEinträge)

    $TextfeldGesamtEintraege = New-Object System.Windows.Forms.Label
    $TextfeldGesamtEintraege.Location = New-Object System.Drawing.Size(140,200)
    $TextfeldGesamtEintraege.Size = New-Object System.Drawing.Size(430,20)
    $Ursprungdatei = Get-Content $PfadUrsprungsdatei
    $TextfeldGesamtEintraege.Text = $($Ursprungdatei.Length)
    $FortschrittFenster.Controls.Add($TextfeldGesamtEintraege)
    
    $FortschrittFenster.Add_Shown({$FortschrittFenster.Activate()})
    [void]$FortschrittFenster.ShowDialog()
}

Function GuiGleicheAnzeigen ($GleicheEingaenge, $GleicheAusgaenge)
{
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

    # Eigenschaften Fenster
    $Fenster = New-Object System.Windows.Forms.Form
    $Fenster.Size = New-Object System.Drawing.Size(905,600) #Breite, Höhe
    $Fenster.StartPosition = "CenterScreen"
    $Fenster.KeyPreview = $true # was macht das?
    $Fenster.MaximumSize = $Fenster.Size # legt fest, dass Größe des Fensters nicht verändert werden kann
    $Fenster.MinimumSize = $Fenster.Size
    $Fenster.Text = "Mehrfach vorhandene Ein- und Ausgänge"

    $Textfeld1 = New-Object System.Windows.Forms.Label
    $Textfeld1.Location = New-Object System.Drawing.Size(10,10)
    $Textfeld1.Size = New-Object System.Drawing.Size(430,20)
    $Textfeld1.Text = "Bei den Eingängen gibt es folgende Duplikate: "
    $Fenster.Controls.Add($Textfeld1)

    $ListeEingänge = New-Object System.Windows.Forms.DataGridView
    $ListeEingänge.Location = New-Object System.Drawing.Size(10,40)
    $ListeEingänge.Size = New-Object System.Drawing.Size(430,20)
    $ListeEingänge.Height = 450
    $ListeEingänge.ColumnCount = 2
    $ListeEingänge.ColumnHeadersVisible = $true
    $ListeEingänge.Columns[0].Name = "Zeile"
    $ListeEingänge.Columns[1].Name = "Kennzeichnung"
    foreach ($GleichenEingang in $GleicheEingaenge)
    {
        Write-Host "Hinzufügen TabelleE: " $GleichenEingang
        $ListeEingänge.Rows.Add($($GleichenEingang.Zeile),($GleichenEingang.Name))
    }
    $Fenster.Controls.Add($ListeEingänge)

    $Textfeld2 = New-Object System.Windows.Forms.Label
    $Textfeld2.Location = New-Object System.Drawing.Size(450,10)
    $Textfeld2.Size = New-Object System.Drawing.Size(430,20)
    $Textfeld2.Text = "Bei den Ausgängen gibt es folgende Duplikate: "
    $Fenster.Controls.Add($Textfeld2)

    $ListeAusgänge = New-Object System.Windows.Forms.DataGridView
    $ListeAusgänge.Location = New-Object System.Drawing.Size(450,40)
    $ListeAusgänge.Size = New-Object System.Drawing.Size(430,20)
    $ListeAusgänge.Height = 450
    $ListeAusgänge.ColumnCount = 2
    $ListeAusgänge.ColumnHeadersVisible = $true
    $ListeAusgänge.Columns[0].Name = "Zeile"
    $ListeAusgänge.Columns[1].Name = "Kennzeichnung"
    foreach ($GleichenAusgang in $GleicheAusgaenge)
    {
        Write-Host "Hinzufügen TabelleA: " $GleichenAusgang
        $ListeAusgänge.Rows.Add($($GleichenAusgang.Zeile),($GleichenAusgang.Name))
    }
    $Fenster.Controls.Add($ListeAusgänge)

    $BestätigenButton = New-Object System.Windows.Forms.Button
    $BestätigenButton.Location = New-Object System.Drawing.Size(10,500)
    $BestätigenButton.Size = New-Object System.Drawing.Size(860,30)
    $BestätigenButton.Text = "Programm beenden"
    $BestätigenButton.Add_Click({
        $Fenster.Dispose()
        return
    })
    $Fenster.Controls.Add($BestätigenButton)

    $Fenster.Add_Shown({$Fenster.Activate()})
    [void]$Fenster.ShowDialog()
}

#------------------- Funktionen für alle GUIs --------------------------

Function PfadExistiert ($Pfad)
{
if ($(Test-Path $Pfad -PathType Container) -or $(Test-Path $Pfad -Include "*.txt"))
{
    # Write-Host "Bei dem Verzeichnis handelt es sich um eine *.txt-Datei oder ein gültiges Verzeichnis"
    return $true
}
else
{
    # Write-Host "Das Verzeichnis existiert nicht oder es wurde keine *.txt-Datei gewählt"
    return $false
}
}

Function LaufwerkeFinden()
{
$Laufwerke = $(Get-PSDrive | Where-Object {$_.Free}).Name
$i = 0

foreach($Laufwerk in $Laufwerke)
{
    $Laufwerke[$i] =  $Laufwerk + ":\"
    $i++
}
return $Laufwerke
}

Function UnterOrdnerFinden($Pfad)
{
# Write-Host "Ordner zum suchen von Unterordnern: " $Pfad
$UnterOrdner = $(Get-ChildItem $Pfad -Directory)
# Write-Host "Gefundene Unterordner: " $UnterOrdner
if ($($UnterOrdner.Length -gt 0))
{
    $Ordner = $(Split-Path $UnterOrdner -Leaf)
}
else {
    $Ordner = ""
}

# Write-Host "Gefundene Ordner: " $Ordner
return $Ordner
}

Function TxtDateienFinden($Pfad)
{
$TxtDateien = $(Get-Childitem $Pfad\*.txt)

if ($TxtDateien.Length -gt 0)
{
    return $(Split-Path $TxtDateien -Leaf)
}
else
{
    return
}
}

Function ReaktionShiftKey ($Pfad, $Auswahl)
{
    if (PfadExistiert $Pfad)
    {
        VERAuswahlBestaetigt $Pfad $Auswahl
    }
    else
    {
        VERAnzeigeAktualisieren ""    
    }

    return
}
#--------------------------------------- Ende Funktionen für GUI -------------------------------

Function ExcelDateiNameErstellen ($Prefix, $PfadUrsprungsdatei, $PfadZielDateien)
{
    $BasisNameZielDatei = Split-Path $PfadUrsprungsdatei -Leaf
    $BasisNameZielDateiLaenge = $BasisNameZielDatei.Length
    $BasisNameZielDateiKurz = $BasisNameZielDatei.Substring(0, $($BasisNameZielDateiLaenge - 4))
    $GesamtPfadZielDatei = $PfadZielDateien + "\" + $Prefix + "_" + $BasisNameZielDateiKurz + ".xlsx"

    return $GesamtPfadZielDatei
}

Function ExcelDateiErstellen ($DateiPfad)
{
    $Datei = New-Object -ComObject Excel.Application
    $Mappe = $Datei.Workbooks.Add()
    $Mappe.SaveAs($DateiPfad)
    $Datei.Quit()

    return
}

Function ExcelDateiBeschreiben ($PfadUrsprungsdatei, $Umwandler1, $Umwandler2, $ZielDatei)
{
    $Datei = New-Object -ComObject Excel.Application
    $Mappe = $Datei.Workbooks.Open($ZielDatei)
    $Blatt = $Mappe.WorkSheets.item(1)
    $Datei.Visible = $false

    $i = 1
    $Wandler1 = @()
    $ZuWandler1 = @(„DI“, „BA“, „BB“, „BC“, „BD“, „BE“, „BF“, „BG“, „BH“, „BJ“, „BK“, „BL“, „BM“, „BN“, „BP“, „BQ“, „BR“, „BS“, „BT“, „BU“, „BV“, „BW“, „BX“, „BY“, „BZ“, „FA“, „FB“, „FC“, „FD“, „FE“, „FF“, „FG“, „FH“, „FJ“, „FK“, „FL“, „FM“, „FN“, „FP“, „FQ“, „FR“, „FS“, „FT“, „FU“, „FV“, „FW“, „FX“, „FY“, „FZ“, „SA“, „SB“, „SC“, „SD“, „SE“, „SF“, „SG“, „SH“, „SJ“, „SK“, „SL“, „SM“, „SN“, „SP“, „SQ“, „SR“, „SS“, „ST“, „SU“, „SV“, „SW“, „SX“, „SY“, „SZ“)
    $Wandler2 = @()
    $ZuWandler2 = @(„DQ“, „CA“, „CB“, „CC“, „CD“, „CE“, „CF“, „CG“, „CH“, „CJ“, „CK“, „CL“, „CM“, „CN“, „CP“, „CQ“, „CR“, „CS“, „CT“, „CU“, „CV“, „CW“, „CX“, „CY“, „CZ“, „EA“, „EB“, „EC“, „ED“, „EE“, „EF“, „EG“, „EH“, „EJ“, „EK“, „EL“, „EM“, „EN“, „EP“, „EQ“, „ER“, „ES“, „ET“, „EU“, „EV“, „EW“, „EX“, „EY“, „EZ“, „GA“, „GB“, „GC“, „GD“, „GE“, „GF“, „GG“, „GH“, „GJ“, „GK“, „GL“, „GM“, „GN“, „GP“, „GQ“, „GR“, „GS“, „GT“, „GU“, „GV“, „GW“, „GX“, „GY“, „GZ“, „HA“, „HB“, „HC“, „HD“, „HE“, „HF“, „HG“, „HH“, „HJ“, „HK“, „HL“, „HM“, „HN“, „HP“, „HQ“, „HR“, „HS“, „HT“, „HU“, „HV“, „HW“, „HX“, „HY“, „HZ“, „KA“, „KB“, „KC“, „KD“, „KE“, „KF“, „KG“, „KH“, „KJ“, „KK“, „KL“, „KM“, „KN“, „KP“, „KQ“, „KR“, „KS“, „KT“, „KU“, „KV“, „KW“, „KX“, „KY“, „KZ“, „MA“, „MB“, „MC“, „MD“, „ME“, „MF“, „MG“, „MH“, „MJ“, „MK“, „ML“, „MM“, „MN“, „MP“, „MQ“, „MR“, „MQ“, „MR“, „MS“, „MT“, „MU“, „MV“, „MW“, „MX“, „MY“, „MZ“, „PA“, „PB“, „PC“, „PD“, „PE“, „PF“, „PG“, „PH“, „PJ“, „PK“, „PL“, „PM“, „PN“, „PP“, „PQ“, „PR“, „PS“, „PT“, „PU“, „PV“, „PW“, „PX“, „PY“, „PZ“, „QA“, „QB“, „QC“, „QD“, „QE“, „QF“, „QG“, „QH“, „QJ“, „QK“, „QL“, „QM“, „QN“, „QP“, „QQ“, „QR“, „QS“, „QT“, „QU“, „QV“, „QW“, „QX“, „QY“, „QZ“, „RA“, „RB“, „RC“, „RD“, „RE“, „RF“, „RG“, „RH“, „RJ“, „RK“, „RL“, „RM“, „RN“, „RP“, „RQ“, „RR“, „RS“, „RT“, „RU“, „RV“, „RW“, „RX“, „RY“, „RZ“, „TA“, „TB“, „TC“, „TD“, „TE“, „TF“, „TG“, „TH“, „TJ“, „TK“, „TL“, „TM“, „TN“, „TP“, „TQ“, „TR“, „TS“, „TT“, „TU“, „TV“, „TW“, „TX“, „TY“, „TZ“)
    $Fehler = @()

    $Ursprungdatei = Get-Content $PfadUrsprungsdatei

    foreach ($Eintrag in $Ursprungdatei)
    {
        $Eintragszeile = $Eintrag.Split("'")
        $BMKZahl = $Eintragszeile[1]
        $BMKZahl = $BMKZahl.TrimStart("'")
        $Kommentar = $Eintragszeile[3]
        $Kommentar = $Kommentar.TrimEnd("'")

        if ($($($BMKZahl.Substring(0,2)) -in $ZuWandler1))
        {
            $BMKZahl = $BMKZahl -replace("[a-zA-Z]","")
            $BMKZahlLaenge = $($BMKZahl.Length - 1)
            $BMKZahl = $BMKZahl.Substring(0,$BMKZahlLaenge) + "." + $BMKZahl.Substring($BMKZahlLaenge)
            $BMKZahl = $Umwandler1 + $BMKZahl
            $Wandler1 += @([PSCustomObject]@{
                Name = $BMKZahl
                Zeile = $i
            })
        }
        elseif ($($($BMKZahl.Substring(0,2)) -in $ZuWandler2))
        {
            $BMKZahl = $BMKZahl -replace("[a-zA-Z]","")
            $BMKZahlLaenge = $($BMKZahl.Length - 1)
            $BMKZahl = $BMKZahl.Substring(0,$BMKZahlLaenge) + "." + $BMKZahl.Substring($BMKZahlLaenge)
            $BMKZahl = $Umwandler2 + $BMKZahl
            $Wandler2 += @([PSCustomObject]@{
                Name = $BMKZahl
                Zeile = $i
            })
        }
        else
        {
            Write-Host "Achtung, Fehler bei " $BMKZahl $Kommentar
            $Fehler += @([PSCustomObject]@{
                Name = $BMKZahl
                Zeile = $i
            })    
        }

        Write-Host "In Excel schreiben: BMKZahl: " $BMKZahl " Kommentar: " $Kommentar
        $Blatt.Cells.Item($i,1)  = $BMKZahl
        $Blatt.Cells.Item($i,2)  = $Kommentar
        
        $i++
    }

    $Mappe.Save()
    $Datei.Quit()

    $GleicheWandler1 = GleicheFinden $Wandler1
    $GleicheWandler2 = GleicheFinden $Wandler2
    Write-Host "Gleiche für " $Umwandler1 ": " $GleicheWandler1
    Write-Host "Gleiche für " $Umwandler2 ": " $GleicheWandler2

    return $GleicheWandler1, $GleicheWandler2
}

Function GleicheFinden ($ZuUeberpruefen)
{
    $ZuUeberpruefen = $ZuUeberpruefen | Sort-Object "Name"
    $Gleiche = @()
    for ($i = 0; $i -lt $($ZuUeberpruefen.Count - 1); $i++)
    {
        $IstGleich = $($ZuUeberpruefen[$i].Name -eq $ZuUeberpruefen[$($i+1)].Name)
        if ($IstGleich)
        {
            # Eintrag hinzufügen
            if (-not $($Gleiche[-1].Zeile -eq $ZuUeberpruefen[$i].Zeile))
            {
                $Gleiche += $ZuUeberpruefen[$i]
            }
            $Gleiche += $ZuUeberpruefen[$($i+1)]
            #Write-Host "Gleiche: " $Gleiche
        }
    }

    if ( $($Gleiche.Length -eq 0))
    {
        $Gleiche += @([PSCustomObject]@{
            Name = "Keine"
            Zeile = "Alle"
        })
    }

    return $Gleiche
}

Main