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

Function Main
{

$StartPfad = "R:\m.kraft\Excel Werte ändern"

$Pfad = Gui $StartPfad #$Laufwerke

# Write-Host "Dateityp nach Übergabe: " $Pfad.GetType()
Write-Host "Dateirückgabe in Main: " $Pfad
}


Function Gui ($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
    TastenReaktionPfadFeld $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.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
    VerzeichnisAuswaehlen $Pfad $Auswahl
})
$ListeOrdnernamen.Add_KeyDown({
    # Reaktion bei gedrückter Taste
    $Taste = $_.KeyCode
    TastenReaktionListeOrdnernamen $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
    VerzeichnisZurueck $Pfad
})
$ZurückButton.Add_KeyDown({
    # Reaktion bei gedrückter Taste
    $Taste = $_.KeyCode
    TastenReaktionButtons $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
    VerzeichnisAuswaehlen $Pfad $Auswahl
})
$AuswählenButton.Add_KeyDown({
    # Reaktion bei gedrückter Taste
    $Taste = $_.KeyCode
    TastenReaktionButtons $Taste
})
$Fenster.Controls.Add($AuswählenButton)

# Dieser Funktionsaufruf zerstört die Rückgabe, wenn er keiner Variable zugewiesen wird
$A = AnzeigeAktualisieren $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 ----------------------------------------------------------------------

Function VerzeichnisAuswaehlen ($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
}

AnzeigeAktualisieren $Pfad

return
}

# Bekommt Pfad, stellt fest ob Laufwerke oder Ordner angezeigt werden müssen und aktualisiert entsprechend alles
# Für Laufwerke muss $Pfad = "" sein
Function AnzeigeAktualisieren ($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 = Optionen $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
{
    AnzeigeAktualisieren ""
}
return
}

Function VerzeichnisZurueck ($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?
}
AnzeigeAktualisieren $Pfad
return
}

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 TastenReaktionPfadFeld($Taste)
{
# Write-Host "Übergebene Taste: " $Taste
switch ($Taste){
    "Return" {
        # Write-Host "Enter gedrückt"
        $Pfad = $PfadFeld.Text
        # Write-Host "Pfad: " $Pfad
        
        if ($Pfad -eq "")
        {
            # Laufwerke aktualisieren
            AnzeigeAktualisieren $Pfad
        }
        elseif (PfadExistiert $Pfad)
        {
            $PfadEnde = $(Split-Path $Pfad -Leaf)
            # Write-Host "Pfadende: " $PfadEnde
            if ($($PfadEnde -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 richtig
                $PfadFeld.Text = $Pfad
                return
            }
            else
            {
                AnzeigeAktualisieren $Pfad
            }
        }
        else
        {
            AnzeigeAktualisieren ""
        }
    }
    default {
        # Write-Host "Gedrückte Taste: " $Taste
    }
}
return
}

Function TastenReaktionListeOrdnernamen($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
        
        VerzeichnisAuswaehlen $Pfad $Auswahl
    }
    "Back" {
        # Write-Host "Back gedrückt"
        $Pfad = $PfadFeld.Text
        # Write-Host "Pfad: " $Pfad

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

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

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

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

foreach($Laufwerk in $Laufwerke)
{
    $Laufwerke[$i] =  $Laufwerk + ":\"
    $i++
}
Write-Host "Rückgabe Laufwerke: " $Laufwerke
return $Laufwerke
}

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

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

Function UnterOrdnerFinden($Pfad)
{
#abfangen: keine Ordner vorhanden -> nicht nötig, da keine weitere Verarbeitung
$Ordner = $(Get-Childitem $Pfad -Directory)
return $Ordner
}

Function Optionen($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
}


Main