#!/usr/bin/wish -f

# *******************************************************************************
# * Converts MIDI to WAV                                                        *
# *                                                                             *
# * GUI for TiMidity, written in Tcl/Tk                                         *
# *                                                                             *
# * Version: 0.0.2                                                              *
# *                                                                             *
# * lastest change:          20.02.2009                                         *
# *                                                                             *
# * build in MP3 converting: 19.02.2009                                         *
# * 1st version 0.0.1:       11.02.2009                                         *
# * birthday:                01.02.2009                                         *
# * Autor: T. Schürmann                                                         *
# *******************************************************************************

set color(background) #b8a58e
set color(border) #cdb89e
# act. directory is current working directory
set SourceDir [pwd]
set DestDir $SourceDir
set mp3too 1
# bitrate for MP3 - set it to a lower or higher value for MP3-quality
# with a bitrate of 128 the quality is sometimes poor
set bitrate 192

proc createMainWindow {} {
  global color fileSelected sourcelist destinationlist mp3too
  wm title . "cMIDI2Wav"
  # wm resizable . 0 0
  #. config -bg $color(border)
  #
  # Menü erstellen
  menu .menu -tearoff 0 -type menubar
  #
  # Datei-Menü
  set m .menu.file 
  menu $m -tearoff 0
  .menu add cascade -label "Datei" -menu $m -underline 0
  $m add command -label "Foo" -command "Foo" -underline 0 -command Foo
  # $m add separator
  $m add command -label "Exit" -command {exit} -underline 0
  #
  # Optionen-Menü
  set m .menu.options 
  menu $m -tearoff 0
  .menu add cascade -label "Optionen" -menu $m -underline 0
  $m add check -label "incl. MP3" -variable mp3too -command Foo
  $m add command -label "Einstellungen" -command "Settings" -underline 0 -command Foo
  $m add command -label "Foo" -command "Foo" -underline 0 -command Foo
  #
  # Hilfe / Info-Menü
  set m .menu.help 
  menu $m -tearoff 0
  .menu add cascade -label "Hilfe" -menu $m -underline 0
  $m add command -label "Info / über" -command "Info" -underline 0 -command InfoMessage
  $m add command -label "Hilfe" -command "Help" -underline 0 -command Foo
  #
  # mit Hauptmenü verbinden
  . configure -menu .menu

  # Anzeigeframe
  frame .board
        # -width 300 -height 400
        # -relief sunken -borderwidth 2 
        # -bg $color(background)
  pack .board -side top -pady 20 -padx 20

  # Linke Seite: Elemente erzeugen und Eigenschaften setzen
  label .board.l1      -text "MIDI-Dateien:" -justify left
  scrollbar .board.h1  -orient horizontal -command ".board.list1 xview"
  scrollbar .board.v1  -orient vertical -command ".board.list1 yview"
  listbox .board.list1 -selectmode single -listvariable sourcelist -width 20 -height 10 \
                       -setgrid 1 -xscroll ".board.h1 set" -yscroll ".board.v1 set"
  label .board.label1  -text "Arbeitsverzeichnis:" -justify left
  entry .board.e1      -textvariable SourceDir

  # Mitte
  # Verzeichniswahl
  button .board.b0     -text ".." -command ChooseWorkingDir
  # Führe Konvertierug aus
  button .board.b1      -text "==>>" -state disabled -command convertmidi2wav
  # Reserve-Button
  button .board.b2      -text "foo" -command Foo

  # Rechte Seite: Elemente erzeugen und Eigenschaften setzen
  label .board.l2      -text "Wave-Dateien:" -justify left
  scrollbar .board.h2  -orient horizontal -command ".board.list2 xview"
  scrollbar .board.v2  -orient vertical -command ".board.list2 yview"
  listbox .board.list2 -selectmode single -listvariable destinationlist -width 20 -height 10 \
                       -setgrid 1 -xscroll ".board.h2 set" -yscroll ".board.v2 set"
  label .board.label2  -text "Datei erzeugen:" -justify left
  entry .board.e2      -textvariable fileChoosed

  # Elemente anordnen
  #
  # Quelle
  grid .board.l1     -row 0 -column 0 -sticky w
  grid .board.list1  -row 1 -column 0 -rowspan 2 -columnspan 2 -sticky "we"
  grid .board.v1     -row 1 -column 2 -rowspan 2 -sticky ns
  grid .board.h1     -row 4 -column 0 -columnspan 2 -sticky "we"
  grid .board.label1 -row 5 -column 0 -sticky w
  grid .board.e1     -row 6 -column 0 -columnspan 6 -sticky "we"
  grid .board.b0     -row 6 -column 6 -sticky e
  #
  # Mittlere Buttons
#  grid .board.b0     -row 1 -column 3 -padx 15 -pady 15
  grid .board.b1     -row 2 -column 3 -padx 15 -pady 15
  # Reserve-Button
  # grid .board.b2     -row 3 -column 3 -padx 15 -pady 15
  #
  # Ziel
  grid .board.l2     -row 0 -column 4 -sticky w
  grid .board.list2  -row 1 -column 4 -rowspan 2 -columnspan 2 -sticky "we"
  grid .board.v2     -row 1 -column 6 -rowspan 2 -sticky ns
  grid .board.h2     -row 4 -column 4 -columnspan 2 -sticky "we"
  # grid .board.label2 -row 5 -column 4 -sticky w
  # grid .board.e2     -row 6 -column 4 -columnspan 3 -sticky "we"

  grid columnconfigure . 0 -weight 1
  grid rowconfigure . 0 -weight 1

  # linkes Listenfeld mit den MIDI-Dateinamen des Verzeichnisses initialisieren
  # ohne -nocomplain kommt es zum Programmabbruch, wenn keine der Maske
  # *.mid entsprechenden Dateien im Verzeichns existieren
  foreach file [glob -nocomplain *.mid *.MID *.Mid] {
       lappend sourcelist $file
       # set .boards.list1 $sourcelist
       # puts $file 
       # puts $sourcelist
  }
  # gleiches mit dem rechten Listenfeld für WAV-Dateien
  # zu -nocomplain siehe oben
  foreach file [glob -nocomplain *.wav] {
       lappend destinationlist $file
  }

  # Aktion bei Mausklick auf Eintrag in der linken Listbox
  bind .board.list1 <ButtonRelease-1> {global fileSelected; .board.b1 configure -state normal; \
                                       set fileSelected [%W get [%W curselection]]}

  # Aktion bei Mausklick auf Eintrag in der rechten Listbox
  # bind .board.list2 <ButtonRelease-1> {global fileChoosed;set fileChoosed [%W get [%W curselection]]}
}

proc ChooseWorkingDir { } {
  global SourceDir sourcelist destinationlist
  # Ohne Vorinitialisierung der temp-Vars kommt es beim Einlesen der Dateimasken (wenn 
  # keine entsprechenden Dateien vorhanden sind) zu einem Fehler, da die Vars sonst nicht existieren. 
  set templist1 ""
  set templist2 ""
  set dir [tk_chooseDirectory -initialdir $SourceDir -title "Arbeitsverzeichnis wählen:"]
  if { $dir eq "" } {
    # do nothing
  } else {
    set SourceDir $dir
    cd $SourceDir
    # neue Dateiliste Source (links) einlesen
    foreach file [glob -nocomplain *.mid *.MID *.Mid] {
      lappend templist1 $file 
    }
    # Source (linke) Liste mit neuen Werten füllen
    lset sourcelist $templist1
    # neue Dateiliste Destination (rechts) einlesen
    foreach file [glob -nocomplain *.wav] {
      lappend templist2 $file 
    }
    # Destination (rechte) Liste mit neuen Werten füllen
    lset destinationlist $templist2
    # Button "==>>" deaktivieren
    .board.b1 configure -state disabled
  }
}

# Aktion bei Button1 = Starte timidity-Konvertierung
proc convertmidi2wav { } {
  global fileSelected mp3too bitrate
  set sourceFile $fileSelected
  set strlen [ string length $sourceFile ]
  set j 0
  if { $strlen > 0 } {
    set destinationFile [ string replace $sourceFile [expr $strlen - 3] $strlen wav ]
    set mp3file [ string replace $sourceFile [expr $strlen - 3] $strlen mp3 ]
    set i [ file exists $destinationFile]

    if { $i == 1 } {
      set j [tk_dialog .info "Achtung" "$destinationFile existiert bereits! Überschreiben?" \
             warning 1 Yes No]
    }
    if { $j == 0 } {
      # Ziel-WAV-Datei noch nicht vorhanden oder die Antwort war 0 = Ja, überschreiben. Nein ergäbe 1
      set n [exec timidity $sourceFile -Ow -o $destinationFile 2> /dev/null]
      puts $n
      if { $mp3too == 1 } {
        # Umwandlung auch nach MP3 
        set n [exec lame -b $bitrate $destinationFile $mp3file 2> /dev/null]
        puts $n
      }
    }
  }
}

# Foo
proc Foo { } {
  # do nothing
}

proc InfoMessage { } {
  tk_dialog .info "Info zu cmidi2wav" \
                  "Konvertierung von MIDI-Dateien (*.mid) in das Format WAV und MP3. Version 0.0.2" \
                  info 0 Ok
}

# Main
createMainWindow

