#!/usr/bin/wish -f

set param(color-frame-bg) \#b0d9d9
set param(color-menu-bg) \#ffffff
set param(color-menu-abg) \#90b9b9
set param(color-menu-afg) \#000000
set param(color-menu-fg) \#000000
set param(color-button-bg) \#b0d9d9
set param(color-button-abg) \#90b9b9
set param(color-button-fg) \#000000
set param(color-text-bg) \#ffffff
set param(color-text-fg) \#000000
set param(color-text-sel) \#cccccc
set param(button-opts) [list -background $param(color-button-bg) \
         -foreground $param(color-button-fg) \
         -activebackground $param(color-button-abg)]

source "./cfglex.tcl"
source "./cfgtree.tcl"
source "./cfgform.tcl"

######################################################################

proc add_root { parent title } {

 if { $parent == "." } {
    set root .mainWindow
    wm withdraw .
 } else {
    set root ${parent}.mainWindow
 }

 toplevel $root
 wm title $root $title
 wm geometry $root 550x300

 return $root
}

######################################################################

proc add_menubar { path } {
  global param

  set menu_opts [list \
         -background $param(color-menu-bg) \
         -foreground $param(color-menu-fg) \
         -activebackground $param(color-menu-abg) \
         -activeforeground $param(color-menu-afg) \
  ]

  set m [eval {menu $path.menu -type menubar} $menu_opts]

  #
  # FILE menu
  #
  eval {menu $m.file -type normal -tearoff 0} $menu_opts
  $m add cascade -menu $m.file -label "File" 
  $m.file add command -label "Load..." -command file_load 
  $m.file add command -label "Save..." -command file_save
  $m.file add command -label "Exit" -command file_exit

  $path configure -menu $m

  return $m
}

######################################################################

proc add_treeFrame { parent } {
    global param

    load_images

    set et [frame $parent.treeFrame]
    $et configure -background $param(color-frame-bg) \
      -relief raised \
      -borderwidth 4

    place $et -x 0 -y 0 -width 200 -height 300
    
    return $et
}

######################################################################

proc add_formFrame { parent } {
    global param
    
    set ef [frame $parent.formFrame]
    $ef configure -background $param(color-frame-bg) \
	-height 200 \
	-width 300 \
	-relief raised \
	-borderwidth 4
    
    place $ef -x 200 -y 0 -width 350 -height 300

    return $ef
}
 
######################################################################

proc dialog_error { message } {
  global param

   tk_dialog  .dlg "Error" "$message" {} 0 "OK"
} 
 
######################################################################

proc file_exit { } { 
  exit
}

######################################################################

proc file_load { } {
  global param

  set dlg [dialog_chooseFile $param(root) "Load"]
  tkwait variable param(ok,chooseFile)
  if { ! $param(ok,chooseFile) } {
    return
  }
  set f "$param(dir,chooseFile)/$param(file,chooseFile)"
  if { ! [file readable $f] } {
      dialog_error "Cannot read file \"$f\""
      return 0
  }
  parse_file $f
}

######################################################################

proc file_save { } {
   global param
}

######################################################################

proc parse_file { f } {
   global param

  set r [catch { source "$f" } msg]
  if { $r } { 
    dialog_error "Error parsing config file:\n$msg"
    return 1
  } 
  make_treedata
  build_tree $param(tree-frame) 
} 
 
######################################################################

proc make_treedata { } {
  global param

  set showcmd   show_form
  set expandcmd expand_toggle
  set nocmd     do_nothing
  set param(data) {}
  foreach n [array names param cfg,groupalias,* ] {
      set nm [lindex [split $n ","] 2]
      set param(state,groupalias,$nm) $param($n)
      lappend param(data) [list groupalias $nm $showcmd "param(state,groupalias,$nm)"]
  }
  foreach n [ array names param cfg,set,* ] {
      set nm [lindex [split $n ","] 2]
      set elist [ list eventset $nm $expandcmd 0 ]
      set sublists {}
      foreach m [ array names param cfg,$nm,* ] {	  
	  set nm2 [lindex [split $m ","] 2]
	  set param(state,option,$nm,$nm2) $param($m)
	  lappend sublists [list option $nm2 $showcmd "param(state,option,$nm,$nm2)"]
      }
      lappend elist $sublists
      lappend param(data) $elist
  }
}

######################################################################

proc do_nothing { type name state } { return }

######################################################################

proc ok_chooseFile { dlg } {
   global param
 
   wm withdraw $dlg 
   set param(ok,chooseFile) 1 
}
 
######################################################################

proc cancel_chooseFile { dlg } {
   global param
  
   wm withdraw $dlg 
   set param(ok,chooseFile) 0 
}

######################################################################

proc dialog_chooseFile { parent command } {
  global param

  if { ! [info exists param(win,chooseFile)] } {
    set w1 15
    set w2 30
  
    set dlg [toplevel $parent.getfn]
    wm title $dlg "$command File"
    set f [frame $dlg.f0 -background $param(color-frame-bg)]
    frame $f.top -background $param(color-frame-bg)
    frame $f.bot -background $param(color-frame-bg)
    # 
    # Draw OK/Cancel Buttons
    #
    set f $f.bot
    eval {button $f.ok  -text "$command" \
                  -command [list ok_chooseFile $dlg]} $param(button-opts)
    eval {button $f.cancel -text "Cancel" \
                  -command [list cancel_chooseFile $dlg]} $param(button-opts)
    pack $f.ok     -side left -anchor center
    pack $f.cancel -side left -anchor center
    #
    # Draw files and dirs windows
    #
    set f $dlg.f0.top
    frame $f.top      -background $param(color-frame-bg)
    frame $f.bot      -background $param(color-frame-bg)
    label $f.top.dirs -text "Directories" \
                      -background $param(color-frame-bg) \
                      -width $w1
    label $f.top.files -text "Files" \
                      -background $param(color-frame-bg) \
                      -width $w2
    scrollbar $f.bot.dsy \
              -orient vertical \
              -width 12 \
              -background $param(color-frame-bg) \
              -activebackground $param(color-menu-abg) \
              -command [list $f.bot.dirs yview]
    scrollbar $f.bot.fsy \
              -orient vertical \
              -width 12 \
              -background $param(color-frame-bg) \
              -activebackground $param(color-menu-abg) \
              -command [list $f.bot.files yview]
    text $f.bot.dirs \
            -width $w1 \
            -background $param(color-text-bg) \
            -foreground $param(color-text-fg) \
            -yscrollcommand [list $f.bot.dsy set]
    text $f.bot.files \
            -width $w2 \
            -background $param(color-text-bg) \
            -foreground $param(color-text-fg) \
            -yscrollcommand [list $f.bot.fsy set]
    pack $f.top.dirs $f.top.files \
            -side left
    pack $f.bot.dirs -side left
    pack $f.bot.dsy  -side left -fill y
    pack $f.bot.files -side left
    pack $f.bot.fsy  -side left -fill y
    pack $f.top $f.bot \
            -side   top \
            -expand 1 \
            -fill   both 
    #
    # Draw dialog box
    #
    pack $dlg.f0.top $dlg.f0.bot \
         -side top
    pack $dlg.f0 \
         -fill both \
         -expand 1
    set param(win,chooseFile) $dlg
  } else {
    set dlg $param(win,chooseFile)
    wm deiconify $dlg
  }
  #
  # Initialize listings and set up bindings
  #
  set param(dir,chooseFile) "."
  set param(file,chooseFile) {}
  set param(tag,chooseFile) {}
  chooseFile_fill

  return $dlg
}

######################################################################

proc chooseFile_fill { } {
  global param

  set dlg $param(win,chooseFile)
  set dir $param(dir,chooseFile)
  set param(file,chooseFile) {}

  set dirs [split [exec ls -aF $dir | grep "\/" ] "\n"]
  #
  # Allow there to be no non-directories listed
  #
  set r [catch {
    set files [split [exec ls -F $dir | grep -v "\/" ] "\n"]
  } ]
  if { $r } {
    set files {}
  }
  #
  # For each side of the widget
  #
  foreach t {dirs files} {
    set i 0
    set w $dlg.f0.top.bot.$t
    $w configure -state normal
    $w delete 1.0 end
    #
    # For each line in the directory listing
    #
    foreach line [set [set t]] {
      incr i
      set start [$w index end]
      set line [string trim $line "@*/|="]
      $w insert end "$line\n"
      $w tag delete $t$i
      $w tag add $t$i $i.0 [list $i.0 lineend]
      switch $t {
       dirs { 
         $w tag bind $t$i <Button-1> { 
           set tg [%W tag names @%x,%y]
           set txt [%W get $tg.first $tg.last]
           if { $param(dir,chooseFile) != "." &&
                $txt == ".." } {
             set x [split $param(dir,chooseFile) "/"] 
             set param(dir,chooseFile) [join [lrange $x 0 [expr [llength $x] - 2]] "/"]
           } else {
             set param(dir,chooseFile) "$param(dir,chooseFile)/$txt"
           }
           chooseFile_fill 
         }
       } 
       files { 
          $w tag bind $t$i <Button-1> {
            %W tag configure $param(tag,chooseFile) -background $param(color-text-bg)
            set tg [%W tag names @%x,%y]
            %W tag configure $tg -background $param(color-frame-bg)
            set txt [%W get $tg.first $tg.last]
            set param(file,chooseFile) $txt
            set param(tag,chooseFile) $tg
          }
        }
      }
    }
  }

  $w configure -state disabled

  return
}
 
######################################################################

set param(root) [add_root . "nlv configuration tool"]
add_menubar $param(root)
set param(tree-frame) [add_treeFrame $param(root)]
set param(form-frame) [add_formFrame $param(root)]
create_forms
if { [llength $argv] > 0 } {
  parse_file $argv
}
