### Copyright (C) 1995 Jesper K. Pedersen
### This program is free software; you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation; either version 2 of the License, or
### (at your option) any later version.
###
### This program is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with this program; if not, write to the Free Software
### Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


############################################################
# setting names of the options, and tk element names
############################################################
set wtypes(checkbox) {checkbutton pack}
set wtypes(radio) {radio packRadio frame packFrame subFrame packSubFrame
  label packLabel}
set wtypes(entry) {entry frame packFrame frameRight packFrameRight
  labelBefore labelAfter packLeft packRight }
set wtypes(int) $wtypes(entry)
set wtypes(float) $wtypes(entry)
set wtypes(textbox) {text scrollbar label packLabel packText
    frame packFrame textFrame packTextFrame}
set wtypes(menu) {menubutton frame packFrame labelBefore
  labelAfter packMenubutton menu}
set wtypes(listbox) {listbox frame packFrame label
    listboxFrame packListboxFrame packLabel scrollbar packListbox}
set wtypes(line) {frame pack}
set wtypes(header) {label packLabel frame packFrame}
set wtypes(label) {label labelBefore labelAfter packLabel frame packFrame}
set wtypes(frame) {frame packFrame}
set wtypes(filloutelm) ""
set wtypes(fillout) {entry packEntry frame packFrame
    label packLabel listbox packListbox scrollbar packScrollbar
    scrollEntry packScrollEntry}
set wtypes(extentry) {frame packFrame label packLabel scrollbar
  packScrollbar subFrame packSubFrame}

set wnames(checkbox) {}
set wnames(radio) {count entries entryhelp}
set wnames(entry) {textafter}
set wnames(int) $wnames(entry)
set wnames(float) $wnames(entry)
set wnames(textbox) {}
set wnames(menu) {entries textafter entryhelp}
set wnames(listbox) {entries entryhelp}
set wnames(line) {}
set wnames(header) {}
set wnames(label) {textafter}
set wnames(frame) {entries orient}
set wnames(filloutelm) {entries change save show}
set wnames(fillout) {entries}
set wnames(extentry) {entries count orient maxentries}
foreach elm [array names wnames] {
  lappend wnames($elm) text default help type
}

############################################################
#                          Basic Objects
############################################################
proc CheckBox {name args} {
  global widgetArgs editInfo
  set function $editInfo(name)
  set widgetArgs(${function}__${name}__default) 0
  widget $name checkbox $args
}
proc Radio {name args} {
  global widgetArgs editInfo
  set function $editInfo(name)
  set widgetArgs(${function}__${name}__default) 0
  set widgetArgs(${function}__${name}__count) 5
  set widgetArgs(${function}__${name}__entryhelp) {}
  widget $name radio $args
  entryhelp2entry ${function}__${name}
}
proc Int {name args} {
  global widgetArgs editInfo
  set function $editInfo(name)
  set widgetArgs(${function}__${name}__default) {}
  set widgetArgs(${function}__${name}__textafter) {}
  widget $name int $args
}
proc Float {name args} {
  global widgetArgs editInfo
  set function $editInfo(name)
  set widgetArgs(${function}__${name}__default) {}
  set widgetArgs(${function}__${name}__textafter) {}
  widget $name float $args
}
proc Entry {name args} {
  global widgetArgs editInfo
  set function $editInfo(name)
  set widgetArgs(${function}__${name}__default) {}
  set widgetArgs(${function}__${name}__textafter) {}
  widget $name entry $args
}
proc TextBox {name args} {
  global widgetArgs editInfo
  set function $editInfo(name)
  set widgetArgs(${function}__${name}__default) {}
  widget $name textbox $args
}
proc Menu {name args} {
  global widgetArgs editInfo
  set function $editInfo(name)
  set widgetArgs(${function}__${name}__default) 0
  set widgetArgs(${function}__${name}__textafter) {}
  set widgetArgs(${function}__${name}__entries) {}
  set widgetArgs(${function}__${name}__entryhelp) {}
  widget $name menu $args
  entryhelp2entry ${function}__${name}
}
proc ListBox {name args} {
  global widgetArgs editInfo
  set function $editInfo(name)
  set widgetArgs(${function}__${name}__selectmode) extended
  set widgetArgs(${function}__${name}__default) {}
  set widgetArgs(${function}__${name}__entries) {}
  set widgetArgs(${function}__${name}__entryhelp) {}
  widget $name listbox $args
  entryhelp2entry ${function}__${name}
}
proc Line {name args} {
  global widgetArgs editInfo
  set function $editInfo(name)
  set widgetArgs(${function}__${name}__default) ""
  widget $name line $args
}
proc Header {name args} {
  global widgetArgs editInfo
  set function $editInfo(name)
  set widgetArgs(${function}__${name}__default) ""
  widget $name header $args
}
proc Label {name args} {
  global widgetArgs editInfo
  set function $editInfo(name)
  set widgetArgs(${function}__${name}__default) ""
  set widgetArgs(${function}__${name}__textafter) {}
  widget $name label $args
}
proc Frame {name args} {
  global children editInfo widgetArgs parent
  set function $editInfo(name)
  set widgetArgs(${function}__${name}__orient) left
  set widgetArgs(${function}__${name}__entries) {}
  set widgetArgs(${function}__${name}__default) {}
  
  widget $name frame $args
  if {$widgetArgs(${function}__${name}__entries) == ""} {
    error "Frame \"$name\" doesn't have an -entries option"
  }
  set children(${function}__$name) $widgetArgs(${function}__${name}__entries)
  foreach var $children(${function}__$name) {
    set newlist [lremove $children(${function}__top) $var]
    if {$newlist == "__error__"} {
      error "element \"$var\" didn't exists for frame \"$name\""
    }
    set children(${function}__top) $newlist
    set parent(${function}__$var) $name
  }
}
############################################################
#                         Fill Outs
############################################################
proc FillOutElm {name args} {
  global widgetArgs editInfo children parent
  set function $editInfo(name)
  set widgetArgs(${function}__${name}__default) ""
  set widgetArgs(${function}__${name}__entries) {}
  set widgetArgs(${function}__${name}__change) ""
  widget $name filloutelm $args

  set children(${function}__$name) $widgetArgs(${function}__${name}__entries)
  if {$widgetArgs(${function}__${name}__text) == ""} {
    set widgetArgs(${function}__${name}__text) $name
  }
  if {![info exists widgetArgs(${function}__${name}__save)]} {
    set widgetArgs(${function}__${name}__save) \
	"print $name"
  }
  if {![info exists widgetArgs(${function}__${name}__show)]} {
    set widgetArgs(${function}__${name}__show) \
	"print \\\[$name\\\]"
  }
  if {![info exists widgetArgs(${function}__${name}__pageEnd)]} {
    set widgetArgs(${function}__${name}__pageEnd) {}
  }
  foreach var $widgetArgs(${function}__${name}__entries) {
    set newlist [lremove $children(${function}__top) $var]
    if {$newlist == "__error__"} {
      error "Element \"$var\" didn't exists for FillOutElm \"$name\""
    }
    set children(${function}__top) $newlist
    set parent(${function}__$var) $name
  }
}
proc FillOut {name args} {
  global children editInfo widgetArgs parent
  set function $editInfo(name)
  set widgetArgs(${function}__${name}__entries) ""
  set widgetArgs(${function}__${name}__default) {}
  widget $name fillout $args
  if {$widgetArgs(${function}__${name}__entries) == ""} {
    error "FillOut \"$name\" doesn't have an -entries option"
  }
  set children(${function}__$name) $widgetArgs(${function}__${name}__entries)
  foreach var $widgetArgs(${function}__${name}__entries) {
    set newlist [lremove $children(${function}__top) $var]
    if {$newlist == "__error__"} {
      error "FillOutElm \"$var\" didn't exist for FillOut \"$name\""
    } 
    set children(${function}__top) $newlist
    set parent(${function}__$var) $name
  }
}
############################################################
#                         ExtEntry
############################################################
proc ExtEntry {name args} {
  global children editInfo widgetArgs parent
  set function $editInfo(name)
  set widgetArgs(${function}__${name}__orient) left
  set widgetArgs(${function}__${name}__count) 3
  set widgetArgs(${function}__${name}__entries) {}
  set widgetArgs(${function}__${name}__default) {}
  set widgetArgs(${function}__${name}__maxentries) Inf
  
  widget $name extentry $args
  if { $widgetArgs(${function}__${name}__count) > \
	   $widgetArgs(${function}__${name}__maxentries)} {
    set widgetArgs(${function}__${name}__count) \
	$widgetArgs(${function}__${name}__maxentries)
  }

  if {$widgetArgs(${function}__${name}__entries) == ""} {
    error "Extentry \"$name\" doesn't have an -entries option"
  }
  set children(${function}__$name) $widgetArgs(${function}__${name}__entries)
  foreach var $widgetArgs(${function}__${name}__entries) {
    set parent(${function}__$var) $name
  }
  foreach var $children(${function}__$name) {
    set newlist [lremove $children(${function}__top) $var]
    if {$newlist == "__error__"} {
      error "element \"$var\" didn't exists for ExtEntry \"$name\""
    }
    set children(${function}__top) $newlist
  }
}
############################################################
#                     Object constructor
############################################################
proc widget {name type rest} {
  global children widgetArgs editInfo checkList parent

  set function $editInfo(name)
  set widgetArgs(${function}__${name}__type) $type

  parseOptions $rest $name

  if {![info exist widgetArgs(${function}__${name}__help)]} {
    set widgetArgs(${function}__${name}__help) "No Help"
  }

  if {[info exists checkList] && [lsearch -exact $checkList $name] != -1} {
    error "two element had the name \"$name\" in function \"$function\""
  }
  if {[info exists checkList]} {
    lappend checkList $name
  }
  lappend children(${function}__top) $name
  set parent(${function}__$name) top
  if {![info exist widgetArgs(${function}__${name}__text)]} {
    set widgetArgs(${function}__${name}__text) ""
  }
}
############################################################
#     This procedure is the general packing procedure.
############################################################
proc packAll {path function new {pack 1}} {
  global children widgetArgs editInfo
  set function $editInfo(name)
  foreach child $children(${function}__top) {
    set default $widgetArgs(${function}__${child}__default)
    set type $widgetArgs(${function}__${child}__type)
    Pack $path $function $child $pack
    if {$new} {
      setVariable $child $function $default
    }
  }
}
############################################################
#     This is the genal procedure for packing objects
############################################################
proc Pack {path prefix name pack {orient top}} {
  global widgetArgs editInfo path2Help var2path

  set function $editInfo(name)
  set default $widgetArgs(${function}__${name}__default)

  set type $widgetArgs(${function}__${name}__type)
  set path2Help($path._$name) $name
  eval pack_$type \"$path\" \"$prefix\" \"$name\" \"$pack\" \"$orient\"

  set var2path(${prefix}_$name) $path
  setState $path $prefix $name
}
############################################################
#          pack procedure for checkbox
############################################################
proc pack_checkbox {path prefix name pack orient} {
  if {$pack} {
    global widgetArgs editInfo TKargs
    set function $editInfo(name)

    set text $widgetArgs(${function}__${name}__text)
    eval checkbutton $path._$name -text \{$text\} -variable ${prefix}_$name \
	-relief flat -command \"makeChange $name $prefix\" \
	$TKargs(${function}__${name}__checkbutton)
    eval pack $path._$name -anchor w -expand 1 -side $orient \
	$TKargs(${function}__${name}__pack)
    bind $path._$name <3> "help $name"
  } else {
    $path._$name configure -variable ${prefix}_$name \
	-command "makeChange $name $prefix"
  }
}
############################################################
#          pack procedure for radio buttons
############################################################
proc pack_radio {path prefix name pack orient} {
  global widgetArgs editInfo ${prefix}_$name TKargs
  set function $editInfo(name)
  set entries $widgetArgs(${function}__${name}__entries)
  set w $path._$name

  if {$pack} {
    set text $widgetArgs(${function}__${name}__text)
    set count $widgetArgs(${function}__${name}__count)
    set frames [min [llength $entries] $count]
    
    eval frame $w $TKargs(${function}__${name}__frame)
    eval pack $w -anchor w -expand 1 -fill x -side $orient \
	$TKargs(${function}__${name}__packFrame)
    
    ### makeing the label
    if {$text != ""} {
      eval label $w.label -text \{$text\} $TKargs(${function}__${name}__label)
      eval pack $w.label -side top -fill x \
	  $TKargs(${function}__${name}__packLabel)
      bind $w.label <3> "help $name"
    }
    ### makeing the subframes
    for {set i 0} {$i <$frames} {incr i} {
      eval frame $w.$i $TKargs(${function}__${name}__subFrame)
      eval pack $w.$i -side left -expand 1 -anchor n \
	  $TKargs(${function}__${name}__packSubFrame)
      bind $w.$i <3> "help $name"
    }
    
    ### inserting the elements
    set i 0
    foreach elm $entries {
      eval radiobutton $w.radio$i -text \{$elm\} -variable ${prefix}_$name \
	  -value $i -command \"makeChange $name $prefix\" \
	  $TKargs(${function}__${name}__radio)
      eval pack $w.radio$i -in $w.[expr $i % $frames] -anchor w \
	  $TKargs(${function}__${name}__packRadio)
      bind $w.radio$i <3> "menu_help $name $i;break"
      bindtags $w.radio$i "$w.radio$i Radiobutton .edit all"
      incr i
    }
  } else {
    set i 0
    foreach elm $entries {
      $w.radio$i configure -variable ${prefix}_$name \
	  -command \"makeChange $name $prefix\"
      incr i
    }
  }
  if {![info exists ${prefix}_$name] || [set ${prefix}_$name] == "" } {
    set ${prefix}_$name 0
  }
}
############################################################
#          pack procedure for entry
############################################################
proc pack_entry {path prefix name pack orient} {
  set w $path._$name
  if {$pack} {
    global widgetArgs editInfo TKargs
    set function $editInfo(name)

    set textBefore $widgetArgs(${function}__${name}__text)
    set textAfter $widgetArgs(${function}__${name}__textafter)

    eval frame $w $TKargs(${function}__${name}__frame)
    eval frame $w.right $TKargs(${function}__${name}__frameRight)

    eval pack $w  -anchor w -expand 1 -fill x -side $orient \
	$TKargs(${function}__${name}__packFrame)

    eval label $w.1 -text \{$textBefore\} \
	$TKargs(${function}__${name}__labelBefore)
    eval entry $w.2 -textvariable ${prefix}_$name -relief sunken \
	$TKargs(${function}__${name}__entry)
    eval label $w.3 -text \{$textAfter\} \
	$TKargs(${function}__${name}__labelAfter)
    eval pack $w.1 -side left -anchor w $TKargs(${function}__${name}__packLeft)
    eval pack $w.right -side right -padx 2 \
	$TKargs(${function}__${name}__packFrameRight)
    eval pack $w.2 $w.3 -in $w.right -side left \
	$TKargs(${function}__${name}__packRight)
    bindtags $w.2 "Entry $path._$name.2 .edit all"

    ### binding help
    foreach elm {"" .right .1 .2 .3} {
      bind $w$elm <3> "help $name"
    }
  } else {
    global ${prefix}_$name
    if {![info exists ${prefix}_$name]} {
      set ${prefix}_$name ""
    }
    $w.2 configure -textvariable ${prefix}_$name
  }
  bind $path._$name.2 <KeyPress> "makeChange $name $prefix"
  bind $path._$name.2 <Button> "makeChange $name $prefix"

}
############################################################
#          pack procedure for int
############################################################
proc pack_int {path prefix name pack orient} {
  pack_entry "$path" "$prefix" "$name" "$pack" "$orient"
  if {$pack} {
    eval $path._$name.2 configure -width 5
    bind $path._$name.2 <KeyPress> "+checkInt %W"
  }
}
############################################################
#          pack procedure for float
############################################################
proc pack_float {path prefix name pack orient} {
  pack_entry "$path" "$prefix" "$name" "$pack" "$orient"
  if {$pack} {
    eval $path._$name.2 configure -width 5
    bind $path._$name.2 <KeyPress> "+checkFloat %W"
  }
}
############################################################
#          pack procedure for textbox
############################################################
proc pack_textbox {path prefix name pack orient} {
  global ${prefix}_$name
  
  global traceTable editInfo TKargs
  set w $path._$name
  set function $editInfo(name)
  if {[info exists traceTable(${function}_$w)]} {
    uplevel \#0 \
	"trace vdelete $traceTable(${function}_$w) w {trace_textbox $w.text}"
    unset traceTable(${function}_$w)
  }
  
  if {$pack} {
    global widgetArgs editInfo
    set function $editInfo(name)
    
    set text $widgetArgs(${function}__${name}__text)
    eval frame $w $TKargs(${function}__${name}__frame)
    eval pack $w -anchor w -expand 1 -fill x -side $orient \
	$TKargs(${function}__${name}__packFrame)
    if {$text != ""} {
      eval label $w.label -text \{$text\} $TKargs(${function}__${name}__label)
      eval pack $w.label -expand 1 -fill x \
	  $TKargs(${function}__${name}__packLabel)
      bind $w.label <3> "help $name"
    }
    eval frame $w.frame $TKargs(${function}__${name}__textFrame)
    eval pack $w.frame $TKargs(${function}__${name}__packTextFrame)
    eval text $w.text -relief raised  -yscrollcommand \"$w.scroll set\" \
	-wrap word -width 40 -height 5 $TKargs(${function}__${name}__text)
    eval scrollbar $w.scroll -command \"$w.text yview\" \
	$TKargs(${function}__${name}__scrollbar)
    eval pack $w.text $w.scroll -side left -fill y -in $w.frame \
	$TKargs(${function}__${name}__packText)

    ### binding help
    foreach elm {"" .frame .text .scroll} {
      bind $w$elm <3> "help $name"
    }
  } else {
    ${path}._$name.text delete 1.0 end
  }
  # I have to enable it, to insert element into it.
  ${path}._$name.text configure -state normal
  global ${prefix}_$name ${prefix}_${name}_scroll
  if {[info exists ${prefix}_$name]} {
    $w.text insert 1.0 [set ${prefix}_$name]
    if {[info exists ${prefix}_${name}_scroll]} {
      $w.text mark set insert [lindex [set ${prefix}_${name}_scroll] 1]
      $w.text yview [lindex [set ${prefix}_${name}_scroll] 0]
    }
  } else {
    set ${prefix}_$name ""
  }
  trace variable ${prefix}_$name w "trace_textbox $w.text"
  set traceTable(${function}_$w) ${prefix}_$name
  bindtags $w.text "Text $w.text .edit all"
  bind $w.text <KeyPress> "set copyingTextBoxFlag 1;set ${prefix}_$name \[$w.text get 1.0 end-1c\];set ${prefix}_${name}_scroll \[list \[$w.text index @1,0\] \[$w.text index insert\]\];set copyingTextBoxFlag 0;makeChange $name $prefix"
}
############################################################
#          pack procedure for menu
############################################################
proc pack_menu {path prefix name pack orient} {
  global ${prefix}_$name widgetArgs editInfo TKargs
  set function $editInfo(name)
  
  set entries $widgetArgs(${function}__${name}__entries)
  set w $path._$name
  if {$pack} {
    set tleft $widgetArgs(${function}__${name}__text)
    set tright $widgetArgs(${function}__${name}__textafter)

    # setting the menu to the first element, in case no default settings exist.
    if {![info exists ${prefix}_$name]} {
      set ${prefix}_$name [lindex $entries 0]
    }    
    eval frame $w $TKargs(${function}__${name}__frame)
    eval pack $w -anchor w -side $orient \
	$TKargs(${function}__${name}__packFrame)
    eval label $w.tleft -text \{$tleft\} \
	$TKargs(${function}__${name}__labelBefore)
    eval label $w.tright -text \{$tright\} \
	$TKargs(${function}__${name}__labelAfter)
    eval menubutton $w.bar -textvariable ${prefix}_$name -indicatoron 1 \
	-menu $w.bar.menu \
	-relief raised -bd 2 -padx 4p -pady 4p -highlightthickness 2 \
	-anchor c $TKargs(${function}__${name}__menubutton)
    eval pack  $w.tleft $w.bar $w.tright -side left \
	$TKargs(${function}__${name}__packMenubutton)
    eval menu $w.bar.menu -tearoff 0 $TKargs(${function}__${name}__menu)
    foreach entry $entries {
      $path._$name.bar.menu add command -label $entry \
	  -command "[list set ${prefix}_$name $entry];makeChange $name $prefix"
    }

    ### binding help
    foreach elm {"" .tleft .tright} {
      bind $w$elm <3> "help $name"
    }
  } else {
    if {![info exists ${prefix}_$name]} {
      set ${prefix}_$name [lindex $entries 0]
    }
    $w.bar configure -textvariable ${prefix}_$name
    set i 0
    foreach entry $entries {
      $path._$name.bar.menu entryconfigure $i \
	  -command "[list set ${prefix}_$name $entry];makeChange $name $prefix"
      incr i
    }
  }
  bind $w.bar <ButtonPress-3> {
    if {$tkPriv(inMenubutton) != ""} {
      tkMbPost $tkPriv(inMenubutton) %X %Y
    }
    break
  }

  bind  $w.bar.menu <ButtonRelease-3> "tkMenuUnpost %W; menu_help $name \[%W index @%y\]; break;"
}
############################################################
#          pack procedure for listbox
############################################################
proc pack_listbox {path prefix name pack orient} {
  global widgetArgs editInfo traceTable ${prefix}_$name \
      ${prefix}_${name}_scroll TKargs
  set function $editInfo(name)
  set text $widgetArgs(${function}__${name}__text)
  set entries $widgetArgs(${function}__${name}__entries)
  set selectmode $widgetArgs(${function}__${name}__selectmode)
  set w $path._$name

  if {[info exists traceTable(${function}_$w)]} {
    uplevel \#0 \
	"trace vdelete $traceTable(${function}_$w) w {trace_listbox $w.box}"
    unset traceTable(${function}_$w)
  }

  if {$pack} {

    eval frame $w $TKargs(${function}__${name}__frame)
    eval pack $w -anchor c -side $orient \
	$TKargs(${function}__${name}__packFrame)
    if {$text != ""} {
      eval label $w.label -text \{$text\} $TKargs(${function}__${name}__label)
      eval pack $w.label -fill x -expand 1 \
	  $TKargs(${function}__${name}__packLabel)
      bind $w.label <3> "help $name"
    }
    eval frame $w.listBoxFrame $TKargs(${function}__${name}__listboxFrame)
    eval pack $w.listBoxFrame -expand 1 \
	$TKargs(${function}__${name}__packListboxFrame)
    eval listbox $w.box -yscrollcommand \"$w.scroll set\" -relief raised \
	-borderwidth 2 -height 5 -exportselection off \
	$TKargs(${function}__${name}__listbox)
    eval scrollbar $w.scroll $TKargs(${function}__${name}__scrollbar) \
	-command \"scroll_listbox $w.box ${prefix}_$name\" 
    eval pack $w.box $w.scroll -side left -fill y \
	$TKargs(${function}__${name}__packListbox) -in $w.listBoxFrame
    foreach entry $entries {
      $w.box insert end $entry
    }

    ### binding help
    foreach elm {""  .listBoxFrame .scroll .box} {
      bind $w$elm <3> "help $name"
    }
  } else {
    $w.box selection clear 0 end
  }
  if {[info exists ${prefix}_${name}_scroll]} {
    eval $w.box yview moveto [lindex [set ${prefix}_${name}_scroll] 0]
  } else {
    eval $w.box yview moveto 0
  }
  if {[info exists ${prefix}_$name]} {
    foreach sel [set ${prefix}_$name] {
      $w.box selection set $sel
    }
  } else {
    set ${prefix}_$name ""
  }
  uplevel \#0 "trace variable ${prefix}_$name w {trace_listbox $w.box}"
  bind $w.box <ButtonRelease-1> "set copyingListBoxFlag 1;set ${prefix}_$name \[$w.box curselection\];set copyingListBoxFlag 0;makeChange $name $prefix"
  bind $w.box <ButtonPress-3> "listbox_help $w $name %y;break"
}
############################################################
#          pack procedure for extEntry
############################################################
proc pack_extentry {path prefix name pack orient} {
  global widgetArgs children editInfo scrollValue traceTable TKargs
  set function $editInfo(name)
  set w $path._$name

  if {[info exists traceTable(${function}_$w)]} {
    uplevel \#0 \
	"trace vdelete $traceTable(${function}_$w) w {trace_scrollbar $w.scroll}"
    unset traceTable(${function}_$w)
  }
  set count $widgetArgs(${function}__${name}__count)
  if {$pack} {
    set text $widgetArgs(${function}__${name}__text)
    set subOrient $widgetArgs(${function}__${name}__orient)
    set maxentries $widgetArgs(${function}__${name}__maxentries)

    ### the frame and the title
    eval frame $w $TKargs(${function}__${name}__frame)
    eval pack $w -side $orient $TKargs(${function}__${name}__packFrame)

    if {$text != ""} {
      eval label $w.header -text \"$text\" $TKargs(${function}__${name}__label)
      eval pack $w.header -expand 1 -fill x \
	  $TKargs(${function}__${name}__packLabel)
      bind $w.header <3> "help $name"
    }

    ### The scrollbar
    eval scrollbar $w.scroll -command \"scroll $w $prefix $name\" \
	$TKargs(${function}__${name}__scrollbar)
    eval pack $w.scroll -side right -fill y -anchor w -expand 1 \
	$TKargs(${function}__${name}__packScrollbar)
    bind $w.scroll <3> "help $name"
    if {![info exists scrollValue(${prefix}_$name)]} {
      set scrollValue(${prefix}_$name) "$count $count 0 [expr $count-1]"
    }
    eval $w.scroll set $scrollValue(${prefix}_$name)
    set widgetArgs(scrollbar) scrollbar
    set offset [lindex $scrollValue(${prefix}_$name) 2]
    
    ### packing recursive
    for {set row 0} {$row < $count} {incr row} {
      eval frame $w.row$row $TKargs(${function}__${name}__subFrame)
      eval pack $w.row$row $TKargs(${function}__${name}__packSubFrame)
      foreach child $children(${function}__$name) {
	Pack $w.row$row ${prefix}_$name[expr $row + $offset] $child 1 $subOrient
      }
      bind $w.row$row <3> "help $name"
    }
  } else {
    if {![info exists scrollValue(${prefix}_$name)]} {
      set scrollValue(${prefix}_$name) "$count $count 0 [expr $count-1]"
    }
    eval $w.scroll set $scrollValue(${prefix}_$name)
    $w.scroll configure -command "scroll $w $prefix $name"
    set offset [lindex $scrollValue(${prefix}_$name) 2]
    for {set row 0} {$row < $count} {incr row} {
      foreach child $children(${function}__$name) {
	Pack $w.row$row ${prefix}_$name[expr $row + $offset] $child 0
      }
    }
  }
  trace variable scrollValue(${prefix}_$name) w "trace_scrollbar $w.scroll"
  set traceTable(${function}_$w) scrollValue(${prefix}_$name)
}
############################################################
#          pack procedure for line
############################################################
proc pack_line {path prefix name pack orient} {
  global TKargs editInfo
  set function $editInfo(name)
  if {$pack} {
    eval frame $path._$name -height 0.05c -relief sunken -bd 1 \
	$TKargs(${function}__${name}__frame)
    eval pack $path._$name -fill x -expand 1 -pady 3 \
	$TKargs(${function}__${name}__pack)
  }
}
############################################################
#          pack procedure for header
############################################################
proc pack_header {path prefix name pack orient} {
  if {$pack} {
    global widgetArgs editInfo TKargs
    set function $editInfo(name)
    set text $widgetArgs(${function}__${name}__text)
    set w $path._$name
    eval frame $w -bd 3 -relief groove $TKargs(${function}__${name}__frame)
    eval pack $w -expand 1 -fill x $TKargs(${function}__${name}__packFrame)

    eval label $w.label -text \{$text\} $TKargs(${function}__${name}__label)
    eval pack $w.label -expand 1 -fill x \
	$TKargs(${function}__${name}__packLabel)

    ### binding help
    foreach elm {"" .label} {
      bind $w$elm <3> "help $name"
    }
  }
}
############################################################
#          pack procedure for label
############################################################
proc pack_label {path prefix name pack orient} {

  set w $path._$name
  if {$pack} {
    global widgetArgs editInfo TKargs
    set function $editInfo(name)

    set textBefore $widgetArgs(${function}__${name}__text)
    set textAfter $widgetArgs(${function}__${name}__textafter)

    eval frame $w $TKargs(${function}__${name}__frame)
    eval pack $w  -anchor w -expand 1 -fill x -side $orient \
	$TKargs(${function}__${name}__packFrame)
    bind $w <3> "help $name"
    if {$textBefore != "" || $TKargs(${function}__${name}__labelBefore) != ""} {
      eval label $w.1 -text \"$textBefore\" \
	  $TKargs(${function}__${name}__labelBefore)
      eval pack $w.1 -side left $TKargs(${function}__${name}__packLabel)
      bind $w.1 <3> "help $name"
    }
    eval label $w.2 -textvariable ${prefix}_$name \
	$TKargs(${function}__${name}__label)
    eval pack $w.2 -side left $TKargs(${function}__${name}__packLabel)
    bind $w.2 <3> "help $name"
    if {$textAfter != "" || $TKargs(${function}__${name}__labelAfter) != ""} {
      eval label $w.3 -text \"$textAfter\" \
	  $TKargs(${function}__${name}__labelAfter)
      eval pack $w.3 -side left $TKargs(${function}__${name}__packLabel)
      bind $w.3 <3> "help $name"
    }

  } else {
    global ${prefix}_$name
    if {![info exists ${prefix}_$name]} {
      set ${prefix}_$name ""
    }
    $w.2 configure -textvariable ${prefix}_$name
  }
}
proc pack_frame {path prefix name pack orient} {
  global widgetArgs children editInfo TKargs
  set function $editInfo(name)
  set w $path._$name
  set subOrient $widgetArgs(${function}__${name}__orient)

  if {$pack} {
    ### packing the frame
    eval frame $w $TKargs(${function}__${name}__frame)
    eval pack $w -side $orient -anchor w -padx 0 -ipadx 0 \
	$TKargs(${function}__${name}__packFrame)
  }

  ### calling recursive
  foreach child $children(${function}__$name) {
    Pack $w ${prefix}_$name $child $pack $subOrient
  }
}
############################################################
#          pack procedure for fillout
############################################################
proc pack_fillout {path prefix name pack orient} {

  set w $path._$name
  if {$pack} {
    global widgetArgs editInfo TKargs
    set function $editInfo(name)
    set text $widgetArgs(${function}__${name}__text)
    set entries $widgetArgs(${function}__${name}__entries)

    ### frame and title
    eval frame $w $TKargs(${function}__${name}__frame)
    eval pack $w -anchor c -expand 1 -side $orient \
	$TKargs(${function}__${name}__packFrame)
    if {$text != ""} {
      eval label $w.1 -text \"$text\" -anchor c \
	  $TKargs(${function}__${name}__label)
      eval pack $w.1 -fill x $TKargs(${function}__${name}__packLabel)
      bind $w.1 <3> "help $name"
    }

    ### entry
    eval entry $w.2 -textvariable ${prefix}_$name -relief sunken \
	-xscrollcommand \"$w.scrollEntry set\" \
	$TKargs(${function}__${name}__entry)
    eval scrollbar $w.scrollEntry -relief sunken -orient horizontal -command \
	\"$w.2 xview\" $TKargs(${function}__${name}__scrollEntry)
    eval pack $w.2 -fill x $TKargs(${function}__${name}__packEntry)
    eval pack $w.scrollEntry -fill x $TKargs(${function}__${name}__scrollEntry)
    focus $w.2
    bindtags $w.2 "$w.2 .edit all"

    ### listbox
    eval listbox $w.box  -relief raised -borderwidth 2 -height 5 \
	-exportselection off $TKargs(${function}__${name}__listbox) \
	-selectmode single
    if {[$w.box cget -height] !=0 && [$w.box cget -height]<[llength $entries]} {
      eval scrollbar $w.scroll -command \"$w.box yview\" \
	  $TKargs(${function}__${name}__scrollbar)
      $w.box configure -yscrollcommand "$w.scroll set"
      eval pack $w.box $w.scroll -side left -fill y \
	  $TKargs(${function}__${name}__packListbox)
      bind $w.scroll <3> "help $name"
    } else {
      eval pack $w.box $TKargs(${function}__${name}__packListbox)
    }

    ### inserting elements in the listbox
    foreach entry $entries {
      set entrytext $widgetArgs(${function}__${entry}__text)
      $w.box insert end $entrytext
    }

    ### binding help
    foreach elm {"" .2 .box} {
      bind $w$elm <3> "help $name"
    }
  } else {
    global ${prefix}_$name
    if {![info exists ${prefix}_$name]} {
      set ${prefix}_$name ""
    }
    $w.2 configure -textvariable ${prefix}_$name
  }
  bind $w.box <ButtonPress-1> "+fillout_list ${prefix}_$name $w $name 1"
  bind $w.box <ButtonPress-3> "fillout_help $w $name %y;break"
  bindtags $w.box "Listbox $w.box .edit"
  
  # bindings for the entry.
  bind $w.2 <KeyPress> \
      "fillOutInsert $w ${prefix}_$name \[$w.2 index insert\] %A %s %K"
  bind $w.2 <1> "fillOutSet $w ${prefix}_$name %x"
}
proc pack_filloutelm {path prefix name pack orient} {
  error "\"$name\" is a FillOutElm which isn't packed in any FillOut"
}
############################################################
#   This function sets the default variables recursive
############################################################
proc setVariable {name prefix default} {
  global widgetArgs children editInfo state
  set function $editInfo(name)
  set type $widgetArgs(${function}__${name}__type)

  if {![info exists state(${prefix}_$name)]} {
    set state(${prefix}_$name) "normal"
  }

  switch -exact $type {
    checkbox -
    int      -
    float    -
    label    -
    entry {
      global ${prefix}_$name
      set ${prefix}_$name $default
    }
    textbox {
      global ${prefix}_$name
      set ${prefix}_$name $default
    }
    radio -
    menu {
      set entries $widgetArgs(${function}__${name}__entries)
      if {$default == ""} {
	# The default value have to be a valid element.
	set default 0
      }
      if {[isIndex $default [llength $entries]]} {
	set index $default
      } else {	
	set index [lsearch -exact $entries $default]
	if {$index == -1} {
	  error "\"$default\" isn't an index or element in Menu $name, should be one of: \"$entries\""
	}
      }
      global ${prefix}_$name
      if {$type == "radio"} {
	set ${prefix}_$name $index
      } else {
	set ${prefix}_$name [lindex $entries $index]
      }
    }
    listbox {
      set entries $widgetArgs(${function}__${name}__entries)
      global ${prefix}_$name
      set ${prefix}_$name {}
      foreach entry $default {
	if {$entry == ""} {
	  # element have to be valid
	  set entry 0
	}
	if {[isIndex $entry [llength $entries]]} {
	  set index $entry
	} else {
	  set index [lsearch -exact $entries $entry]
	  if {$index == -1} {
	    error "\"$entry\" isn't a index or element in ListBox \"$name\", should be one of: \"$entries\""
	  }
	}
	lappend ${prefix}_$name $index
      }
    }
    
    extentry {
      global scrollValue
      set count $widgetArgs(${function}__${name}__count)
      set maxentries $widgetArgs(${function}__${name}__maxentries)
      set row 0
      set diff1 0
      set diff2 0
      if {$maxentries != "inf"} {
	set diff1 [expr $maxentries - [llength $default]]
      }
      if {$count > [llength $default]} {
	set diff2 [expr $count - [llength $default]]
      }
      if {$diff1 > 0 || $diff2 > 0} {
	for {set i 0} {$i < [max $diff1 $diff2]} {incr i} {
	  lappend default {}
	}
      }
      foreach value $default {
	set i 0
	foreach child $children(${function}__$name) {
	  set type $widgetArgs(${function}__${child}__type)
	  if {$type == "header" || $type == "line"} continue
	  
	  setVariable $child ${prefix}_$name$row [lindex $value $i]
	  incr i
	}
	incr row
      }

      # setting the scrollbar
      set noOfEntries [llength $default]
      set scrollValue(${prefix}_${name}) \
	  "[max $noOfEntries $count] $count 0 [expr $count -1]"
    }
    fillout {
      fillOut_setDefault $name $prefix $default
    }
    frame {
      set i 0
      foreach child $children(${function}__$name) {
	setVariable $child ${prefix}_$name [lindex $default $i]
	incr i
      }
    }
  }
}
############################################################
#                      scroll bars
############################################################
proc scroll {path prefix name newTop} {
  global widgetArgs scrollValue children editInfo initFunc changeElm \
      changeFunc activeNivau
  set function $editInfo(name)
  
  if {$newTop < 0} {set newTop 0}
  set count $widgetArgs(${function}__${name}__count)
  set maxentries $widgetArgs(${function}__${name}__maxentries)

  # reading the scrollbar
  set scrollbar ${path}.scroll
  set totalUnit [lindex [$scrollbar get] 0]
  set windowUnits [lindex [$scrollbar get] 1]
  set oldTop [lindex [$scrollbar get] 2]
  set oldBot [lindex [$scrollbar get] 3]

  if {[expr $newTop+$windowUnits] > $maxentries} {
    set newTop [expr $maxentries-$windowUnits]
  }
  set scrollCount [expr $newTop - $oldTop]


  # setting the scrollbar
  if {[expr $newTop+$windowUnits] > $totalUnit} {
    set totalUnit [expr $newTop+$windowUnits]
    set new 1
  } else {
    set new 0
  }
  
  set bar "$totalUnit $windowUnits $newTop [expr $newTop+$windowUnits-1]"
  eval $scrollbar set $bar
  set scrollValue(${prefix}_$name) $bar

  for {set row 0} {$row < $count} {incr row} {
    foreach child $children(${function}__$name) {
      Pack $path.row$row ${prefix}_$name[expr $row+$newTop] $child 0
    }
  }

  # removing the active element from this extentry and below.
  unlink $name
  resetBelow $name

  # calling the init or change function
  if {$new} {
    set childs $children(${function}__$name)
    UpdateActive [lindex $childs 0] ${prefix}_${name}[expr $totalUnit-1]
    if {[info exists initFunc($function)]} {
      set changeElm $name
      uplevel \#0 $initFunc($function)
    } else {
      set activeNivau($name) [expr $totalUnit-1]
      foreach child $childs {
	changeAll $child
      }
    }
  }
  
}
############################################################
#              trace funktion
############################################################
proc trace_textbox {path variable subvar operation} {
  global copyingTextBoxFlag
  if {[info exists copyingTextBoxFlag] && $copyingTextBoxFlag == 1} return
  if {[info command $path] == ""} {
    # the path has disapeared, but we forgot to remove the trace
    uplevel \#0 trace vdelete $variable $operation \"trace_textbox $path\"
    return
  }
  upvar $variable x
  set insert [$path index insert]
  $path delete 1.0 end
  $path insert 1.0 $x
  $path mark set insert $insert
}
proc trace_listbox {path variable subvar operation} {
  global copyingListBoxFlag
  upvar $variable x
  if {[info exists copyingListBoxFlag] && $copyingListBoxFlag == 1} return
  if {[info command $path] == ""} {
    # the path has disapeared, but we forgot to remove the trace
    uplevel \#0 trace vdelete $variable $operation \"trace_listbox $path\"
    return
  }
  $path selection clear 0 end
  foreach index $x {
    $path selection set $index
  }
}
proc trace_scrollbar {path variable subvar operation} {
  upvar $variable x
  if {[info command $path] == ""} {
    # the scrollbar has disapear, remove the trace
    uplevel \#0 trace vdelete ${variable}($subvar) $operation \"trace_scrollbar $path\"
    return
  }
  eval $path set $x($subvar)
}
proc scroll_listbox {path prefix args} {
  global ${prefix}_scroll
  eval $path yview $args
  set ${prefix}_scroll [$path yview]
}
############################################################
# This function takes care of the states of the widgets
############################################################
proc setState {path prefix name} {

  global widgetArgs state editInfo
  set function $editInfo(name)
  set type $widgetArgs(${function}__${name}__type)
  if {![info exists state(${prefix}_$name)]} {
    set state(${prefix}_$name) "normal"
  }

  switch $type {
    checkbox {
      $path._$name configure -state $state(${prefix}_$name)
    }
    entry -
    int -
    float {
      $path._$name.2 configure -state $state(${prefix}_$name)
    }
    radio {
      set entries $widgetArgs(${function}__${name}__entries)
      set i 0
      foreach elm $entries {
	$path._$name.radio$i configure -state $state(${prefix}_$name)
	incr i
      }
    }
    textbox {
      $path._$name.text configure -state $state(${prefix}_$name)
      set w $path._$name
      if {$state(${prefix}_$name) == "normal"} {
	$w.scroll configure -command "$w.text yview"
      } else {
	$w.scroll configure -command ""
      }
    }
    menu {
      $path._$name.bar configure -state $state(${prefix}_$name)
    }
    listbox {
      set w $path._$name
      if {$state(${prefix}_$name) == "normal"} {
	# nothing to be done...things done in Pack
	$w.scroll configure -command "scroll_listbox $w.box ${prefix}_$name"
	bindtags $w.box "Listbox $w.box .edit all"
      } else {
	bind $w.box <Enter> ""
	bind $w.box <ButtonRelease-1> break
	bind $w.box <ButtonPress-1> break
	bindtags $w.box {$w.box .edit}
	$w.scroll configure -command ""
      }
    }
    extentry {
      set w $path._$name
      if {$state(${prefix}_$name) == "normal"} {
	$w.scroll configure -command "scroll $w $prefix $name"
      } else {
	$w.scroll configure -command ""
      }
    }
    fillout {
      set w $path._$name
      if {$state(${prefix}_$name) == "normal"} {
	bindtags $w.2 "$w.2  .edit all"
	bindtags $w.box "Listbox $w.box .edit all"
	if {[info command $w.scroll] != ""} {
	  bindtags $w.scroll "$w.box Scrollbar .edit all"
	}
	bindtags $w.scrollEntry "$w.box Scrollbar .edit all"
      } else {
	bindtags $w.2 {None}
	bindtags $w.box {None}
	if {[info command $w.scroll] != ""} {
	  bindtags $w.scroll {None}
	}
	bindtags $w.scrollEntry {None}
      }  
    }
    line   -
    header -
    frame -
    label  {}
    default {
      error "unknow type $type"
    }
  }
}
############################################################
#        This function makes the entries list
#        from the entryhep list
############################################################  
proc entryhelp2entry {prefix} {
  global widgetArgs
  if {$widgetArgs(${prefix}__entryhelp) != ""} {
    set count 0
    set widgetArgs(${prefix}__entries) ""
    foreach elm $widgetArgs(${prefix}__entryhelp) {
      if {$count%2 == 0} {
	lappend widgetArgs(${prefix}__entries) $elm
      }
      incr count
    }
  }
}

############################################################
# this procedure parses the list of elements given to a
# command linke CheckBox, and sort out those for TK.
############################################################
proc parseOptions {list name} {
  global widgetArgs TKargs editInfo wtypes wnames

  set function $editInfo(name) 
  set option ""
  set widget ""
  set nextValue 0
  set type $widgetArgs(${function}__${name}__type)

  # setting blanks for all tk options
  foreach widget $wtypes($type) {
    set TKargs(${function}__${name}__$widget) ""
  }
  set widget ""
  
  foreach var $list {
    if {[string index $var 0] == "-" && [string index $var 1] != "-"} {
      if {$nextValue == 1} {
	error "No value to option \"$option\" in \"$name\""
      }

      # seting the tk option for the last element.
      if {$widget != ""} {
	append TKargs(${function}__${name}__$widget) \
	  " -$option $widgetArgs(${function}__${name}__$option)"
      }

      set nextValue 1
      set option [string range $var 1 end]
      set first 1

      # checking if the option is one for TK
      if {[lsearch $wnames($type) $option] == -1} {
	# the option name was not one of the standard options like
	# -text -default etc.
	if {![regexp {^([^:]+):([^:]+)$} $option all widget option]} {
	  # There were no colon in the name, so the option goes to the
	  # default element.
	  set widget [lindex [split $wtypes($type)] 0]
	} else {
	  # a colon was found so we now know the widget and the option
	  # so lets check if the widget is known
	  if {[lsearch -exact $wtypes($type) $widget] == -1} {
	    error [concat "bad widget: \"$widget\" in option $all," \
		       "should be one of: \"$wtypes($type)\""]
	  }
	}
      } else {
	set widget ""
      }
    } else {
      set nextValue 0
      if {$option == ""} {
	error [concat "value without option: \"$name\"" \
		   "in $function, input string: \"$var\""]
      }
      if {[string index $var 0] == "-"} {
	set var [string range $var 1 end]
      }
      if {[info exists widgetArgs(${function}__${name}__$option)] & !$first} {
	append widgetArgs(${function}__${name}__$option) " $var"
      } else {
	set widgetArgs(${function}__${name}__$option) $var
      }
      set first 0
    }
  }
  
  # seting the tk option for the last element.
  if {$widget != ""} {
    append TKargs(${function}__${name}__$widget) \
	" -$option $widgetArgs(${function}__${name}__$option)"
  }
}
