#!/usr/local/bin/wish -f
#
# $Source: /home/catless/nlfm/Working/Obeah/RCS/obeah,v $
# $Date: 1994/08/22 14:01:31 $
# $Revision: 1.2.1.5 $
#
# ----------------------------------------------------------------------
#   AUTHOR:  Lindsay Marshall <lindsay.marshall@newcastle.ac.uk>
# ----------------------------------------------------------------------
# Copyright 1994 The University of Newcastle upon Tyne (see COPYRIGHT)
# ======================================================================
#
proc ob_makeArray {args} {
    foreach x $args {
	global $x
	set ${x}(1) 1
	unset ${x}(1)
    }
}
#
proc ob_tellUser {what} {
    .msg configure -text $what
    update
}
#
proc ob_tellError {msg} {
    tk_dialog .derr Error $msg error 0 OK
}
#
proc ob_flagError {msg} {
    if {![winfo exists .error]} {
	toplevel .error -class Obeah
	wm minsize .error 1 1
	wm title .error {Verify Errors}
	frame .error.txt
	text .error.msg -relief raised -state disabled -wrap word \
	  -yscrollcommand {.error.sb set} -height 16
	scrollbar .error.sb -command {.error.msg yview}
	button .error.quit -text Dismiss -command "destroy .error"
	pack .error.msg -fill both -expand 1 -side left -in .error.txt
	pack .error.sb -fill y -side right -in .error.txt
	pack .error.txt -fill both -expand 1
	pack .error.quit -fill x
    }
    .error.msg configure -state normal
    .error.msg insert end "$msg\n"
    .error.msg configure -state disabled
}
#
proc ob_setHelp {} {
    global obeah
    if {$obeah(helpOn)} {
	pack .help -after .msg -fill x -pady 5
    } {
	pack forget .help
    }
}
#
proc ob_changed {} {
    global obeah
    set obeah(altered) 1
    .ctl.save configure -state normal
    if {$obeah(cMode)} { .create.ctl.save configure -state normal }
}
#
proc ob_showHelp {what} {
    global obeah help
    if {$obeah(helpOn)} {
	.help configure -state normal
	.help delete 1.0 end
	if {[info exists help($what)]} {
	    regsub -all {%n} $help($what) $what val
	    regsub -all {%p} $help($what) $obeah(program) val
	    .help insert end $val
	}
	.help configure -state disabled
    }
}
#
proc ob_LabelEntry {lab name args} {
    global config default label
    if {![info exists config($lab)]} {
	if {[info exists default($lab)]} {
	    set config($lab) $default($lab)
	} {
	    set config($lab) {}
	    set default($lab) {}
	}
    } \
    elseif {![info exists default($lab)]} {
	set default($lab) $config($lab)
    }
    frame $name
    label $name.label -text $label($lab)
    eval $name.label configure $args
    bind $name <Any-Enter> "ob_showHelp $lab ; focus $name.entry"
    entry $name.entry -relief sunken -width 40 -textvariable config($lab)
    bind $name.entry <Escape> "
	global config default
	set config($lab) \$default($lab)
	ob_changed
    "
    bind $name.entry <Shift-Escape> "
	global config
	set config($lab) {}
	ob_changed
    "
    pack $name.label -side left -padx 5
    pack $name.entry -side left -fill x -expand 1
}
#
proc ob_wishCheck {wish cmd patrn msg} {
    set ans 1
    set desc [open "|$wish" r+]
    puts $desc "puts stdout \[$cmd\] ; exit"
    flush $desc
    set res [read $desc]
    if {![regexp -- $patrn $res]} {
	ob_flagError "$wish $msg"
	set ans 0
    }
    catch {close $desc}
    return $ans
}
#
proc ob_nextBind {from to} {
    bind $from.entry <Return> "focus $to.entry"
    catch {bind $from.entry <Key-KP_Enter> "focus $to.entry"}
    bind $from.entry <Key-Tab> "focus $to.entry"
    bind $from.entry <Control-i> "focus $to.entry"
    bind $from.entry <Down> "focus $to.entry"
    bind $to.entry <Up> "focus $from.entry"
}
#
proc ob_putLog {msg} {
    .log.msg configure -state normal
    .log.msg insert end "$msg\n"
    .log.msg configure -state disabled
}
#
proc ob_log {cmd} {
    global obeah
    if {![winfo exists .log]} {
	toplevel .log -class Obeah
	wm minsize .log 1 1
	wm title .log "$obeah(program) make log"
	frame .log.txt
	text .log.msg -relief raised -state disabled -wrap word \
	  -yscrollcommand {.log.sb set} -height 16
	scrollbar .log.sb -command {.log.msg yview}
	button .log.quit -text Dismiss -command "destroy .log"
	pack .log.msg -fill both -expand 1 -side left -in .log.txt
	pack .log.sb -fill y -side right -in .log.txt
	pack .log.txt -fill both -expand 1
	pack .log.quit -fill x -side bottom
    }
    if {[catch {set desc [open "|$cmd" r]} msg]} {
	ob_tellUser "Cannot execute make : $msg"
	return
    }
    ob_putLog "% $cmd"
    while {![eof $desc]} { ob_putLog "[gets $desc]" }
    if {[catch {close $desc} msg]} {
	ob_tellUser "\"[lindex $cmd 0]\" failed"
	ob_putLog $msg
    }
    update
}
#
proc ob_makeVars {} {
    global config makeVar
    set res {}
    foreach x [lsort [array names config]] {
	if {![string match {!*} $x]} {
	    regsub -all {([ 	])} $config($x) {\\&} v
	    append res " $makeVar($x)=$v"
	}
    }
    return $res
}
#
# Value verification procs
#
proc ob_dirCheck {dir} {
    set ans 1
    if {![file exists $dir]} {
	if {![file writable [file dirname $dir]]} {
	    ob_flagError \
	"$dir does not exist and you have no write permission for its parent."
	    set ans 0
	}
    } \
    elseif {![file isdirectory $dir]} {
	ob_flagError "$dir is not a directory."
	set ans 0
    } \
    elseif {![file writable $dir]} {
	ob_flagError "You have no write permission for $dir."
	set ans 0
    }
    return $ans
}
#
proc ob_interpCheck {actions wish} {
    set ans 1
    if {![file exists $wish]} {
	ob_flagError "$wish does not exist."
	set ans 0
    } \
    elseif {![file executable $wish]} {
	ob_flagError "You cannot execute $wish."
	set ans 0
    } \
    elseif {![ob_wishCheck $wish {puts stdout check} {^check.*} \
      {is not a tcl interpreter}]} {
	set ans 0
    } {
	foreach x $actions {
	    set ans [ob_wishCheck $wish [lindex $x 0] [lindex $x 1] [lindex $x 2]]
	}
    }
    return $ans
}
#
proc ob_verify {} {
    global check obeah config label
    if {[winfo exists .error]} {
	.error.msg delete 1.0 end
    }
    set ans 1
    foreach x [lsort [array names check]] {
	if {$check($x) != {}} {
	    ob_tellUser "Checking $label($x)"
	    if {![eval $check($x) $config($x)]} {
		set ans 0
	    }
	}
    }
    if {$ans} {
	ob_tellUser {Verify succeeded}
    } {
	ob_tellUser {Verify failed}
    }
    set obeah(verified) $ans
    return $ans
}
#
proc  ob_quit {} {
    global obeah
    if {$obeah(altered) && [tk_dialog .save Save \
      "You have made changes. Do you wish to save them?" \
      warning 0 No Yes] == 1} {
	ob_save
    }
    exit
}
#
proc ob_clear {} {
    global config window
    foreach x [array names config] {
	if {![string match { *} $x]} { $window($x).entry delete 0 end }
    }
    ob_changed
}
#
proc ob_reset {} {
    global config window default
    foreach x [array names config] {
	if {![string match { *} $x]} {
	    if {[info exists default($x)]} {
		set config($x) $default($x)
	    } {
		set config($x) {}
	    }
	}
    }
    ob_changed
}
#
proc ob_install {} { ob_runMake install }
#
proc ob_run {cmd} { ob_log $cmd }
#
proc ob_runMake {args} {
    global obeah
    ob_log "make -f $obeah(makefile) [ob_makeVars] $args"
}
#
proc ob_makeMF {} {
    global config makeVar obeah
    set desc [open Makefile w]
    foreach x [lsort [array names config]] {
	if {![string match {!*} $x]} {
	    puts $desc "$makeVar($x)	= $config($x)"
	}
    }
    close $desc
    exec cat $obeah(makefile) >>Makefile
}
#
proc ob_fBind {frm} {
    set l [winfo children $frm]
    if {[set x [lsearch -exact $l "$frm.none"]] >= 0} {
	set l [lreplace $l $x $x]
    }
    set fst [lindex $l 0]
    set prv $fst
    foreach x $l {
	ob_nextBind $fst $x
	set prv $x
    }
    if {$fst != {}} { ob_nextBind $x $fst }
}
#
proc ob_vWindow {frm txt ptn prc width} {
	global window label obeah
	set w [frame .conf.$frm]
	set none 1
	foreach x [lsort [array names label]] {
	    if {[string match $ptn $x]} {
		ob_LabelEntry $x $w.$x -width $width
		set window($x) $w.$x
		pack $w.$x -fill x
		if {$obeah(cMode)} {
		    bind $w.$x.label <Double-1> "$prc $x"
		}
		set none 0
	    }
	}
	label $w.none -text "No $txt Values"
	if {$none} {
	    pack $w.none -fill x -padx 10
	} {
	    ob_fBind $w
	}
	pack $w
}
#
proc ob_configWindow {} {
    global config obeah help action window label delete
    wm minsize . 1 1
    wm title . "$obeah(program) configuration"
    frame .conf -relief raised
    set w 0
    foreach x [array names label] {
	if {[string match {[if]*} $x] && [string length $label($x)] > $w} {
	    set w [string length $label($x)]
	}
    }
#
    ob_vWindow f Configurable {f*} obc_field $w
#
    if {$obeah(cMode)} { ob_vWindow i Invisible {i*} obc_invisible $w }
#
    pack .conf -fill x
    label .msg -relief raised
    pack .msg -fill x
    bind .msg <Any-Enter> {ob_showHelp !.msg}
    set help(!.msg) {Messages are displayed here.}
    text .help -borderwidth 2 -state disabled -height 4 -wrap word -width 50
    bind .help <Any-Enter> {ob_showHelp !.help}
    set help(!.help) {Help information is displayed here.}
    frame .ctl -relief raised
    set help(!quit) {Clicking the Quit button will exit the configuration program.}
    set help(!clear) {Clicking the Clear button will clear all the fields.}
    set help(!reset) {Clicking the Reset button will restore the default \
configuration values.}
    set help(!verify) {Clicking the Verify button will validate the values\
you have provided for the fields.}
    set help(!save) {Clicking the Save button will save your configuration info.}
    set help(!install) {Clicking the Install button will attempt to install %p and will save your configuration.}
    foreach x {Quit Reset Clear Verify Save Install} {
	set lx [string tolower $x]
	if {[info exists delete(!$lx)]} { continue }
	button .ctl.$lx -text $x -command ob_$lx
	bind .ctl.$lx <Any-Enter> "[bind Button <Any-Enter>]
ob_showHelp !$lx"
	if {$obeah(cMode)} { bind .ctl.$lx <Shift-1> "obc_control !$lx" }
	pack .ctl.$lx -side left -fill x -expand 1
    }
    .ctl.save configure -state disabled
    if {$obeah(cMode)} {.ctl.quit configure -state disabled}
    foreach x [lsort [array names action]] {
	button .ctl.$x -text $label($x) -command $action($x)
	bind .ctl.$x <Any-Enter> "[bind Button <Any-Enter>]
ob_showHelp b$x"
	if {$obeah(cMode)} { bind .ctl.$x <Shift-1> "obc_control $x" }
	pack .ctl.$x -side left -fill x -expand 1
	set window(b$x) .ctl.$x
    }
    checkbutton .ctl.help -text Help -variable obeah(helpOn) \
      -command ob_setHelp
    set help(!help) {Checking the Help flag will cause help information \
to be displayed.}
    bind .ctl.help <Any-Enter> "[bind Button <Any-Enter>]
    ob_showHelp !help"

    pack .ctl.help -side left
    pack .ctl -fill x -side bottom
}
#
proc obc_exit {} { ob_quit }
#
proc obc_save {} { ob_save }
#
proc ob_save {} {
    global config help check action makeVar default cMode \
      label delete obeah

    if {$obeah(cfFile) == {}} {
	ob_tellError "No config file specified."
	return 0
    }
    ob_tellUser "Saving configuration in \"$obeah(cfFile)\""
    if {[catch {set desc [open $obeah(cfFile) w]} msg]} {
	ob_tellError "Error opening $obeah(cfFile) for write : $msg"
	return 0
    }
    puts $desc {# ************ Use the configuration system to change this file ****}
    foreach x [lsort $obeah(procs)] {
	puts $desc "#\nproc $x {[info args $x]} {[info body $x]}"
    }
    puts $desc "#\nset obeah(program) {$obeah(program)}"
    puts $desc "set obeah(cfFile) {$obeah(cfFile)}"
    puts $desc "set obeah(cfProg) {$obeah(cfProg)}"
    puts $desc "set obeah(makefile) {$obeah(makefile)}"
    puts $desc "set obeah(creator) {$obeah(version)}"
    foreach v {config default} {
	puts $desc {#}
	foreach x [lsort [array names $v]] {
	    if {![string match {!*} $x]} {
		if {[regexp {^=(.*)} [set ${v}($x)] m xpr]} {
		    puts $desc "set ${v}($x) $xpr"
		} {
		    puts $desc "set ${v}($x) {[set ${v}($x)]}"
		}
	    }
	}
    }
    foreach v {label help check makeVar action} {
	puts $desc {#}
	foreach x [lsort [array names $v]] {
	    if {![string match {!*} $x]} {
		puts $desc "set ${v}($x) {[set ${v}($x)]}"
	    }
	}
    }
    puts $desc {#}
    foreach x [lsort [array names delete]] {
	puts $desc "set delete($x) 1"
    }
    close $desc
    set obeah(altered) 0
    .ctl.save configure -state disabled
    if {$obeah(cMode)} { .create.ctl.save configure -state disabled }
    return 1
}
#
proc obc_program {} {
    global obeah
    if {[catch {set desc [open $obeah(cfProg) w]} msg]} {
	ob_tellUser "Cannot create file \"$obeah(cfProg)\" : $msg"
	return
    }
    ob_tellUser "Creating program script in \"$obeah(cfProg)\""
    puts $desc "#!/bin/sh
#
# Configuration program for $obeah(program) created from code
# ----------------------------------------------------------------------
#   AUTHOR:  Lindsay Marshall <lindsay.marshall@newcastle.ac.uk>
# ----------------------------------------------------------------------
# Copyright (c) 1994 The University of Newcastle upon Tyne
#======================================================================
#
# This script created [exec date]
#
exec wish <<'+'"
    foreach p [lsort [info procs ob_*]] {
	puts $desc "#\nproc $p {[info args $p]} {[info body $p]}"	
    }
    puts $desc "#\nob_main {$obeah(cfFile)}\n+"
    close $desc
    exec chmod a+rx $obeah(cfProg)
}
#
proc obc_delField {win edit} {
    global window config check makeVar help label default
    if {$edit == {}} { set edit [string trim $config(!flabel)] }
    if {[info exists window($edit)]} {
	set prnt [winfo parent $window($edit)]
	destroy $window($edit)
	foreach x {window config check makeVar help label default} {
	    catch {unset ${x}($edit)}
	}
	if {[winfo children $prnt] == "$prnt.none"} {
	    pack $prnt.none -fill x
	} {
	    ob_fBind $prnt
	}
    }
    ob_changed
}
#
proc obc_doField {frm prc fname} {
    global config help check window makeVar label
    if {[set name $fname] == {}} {
	if {[set l [winfo children .conf.$frm]] == ".conf.$frm.none"}  {
	    pack forget .conf.$frm.none
	    set name ${frm}0
	} {
	    set x [lsearch $l ".conf.$frm.none"]
	    set l [lreplace $l $x $x]
	    regexp "^\\.conf\\.${frm}\\.${frm}(\[0-9\]*)" \
	      [lindex $l [expr [llength $l] - 1]] m name
	    incr name
	    set name "${frm}${name}"
	}
    }
    set label($name) [string trim $config(!${frm}label) ]
    set config($name) $config(!${frm}def)
    set makeVar($name) $config(!${frm}make)
    set help($name) $config(!${frm}help)
    set check($name) $config(!${frm}check)
    if {[info exists window($name)]} {
	$window($name).label configure -text $label($name)
    } {
	ob_LabelEntry $name .conf.$frm.$name
	bind .conf.$frm.$name.label <Double-1> "$prc {$name}"
	pack .conf.$frm.$name -fill x
	set window($name) .conf.$frm.$name
	if {[llength [array names window]] > 1} {
	    set w 0
	    foreach x [array names label] {
		if {[string match {[if]*} $x] && 
		  [string length $label($x)] > $w} {
		    set w [string length $label($x)]
		}
	    }
	    foreach x [array names window] {
		if {[string match {[if]*} $x]} {
		    $window($x).label configure -width $w
		}
	    }
	}
	ob_fBind .conf.$frm
    }
    ob_changed
}
#
proc obc_field {args} { obc_makeField .field Field f obc_field [lindex $args 0] }
#
proc obc_invisible {args} {
    obc_makeField .invis  {Invisible Field} i obc_invisible [lindex $args 0]
}
#
proc obc_makeField {win txt frm prc edit} {
    if {[winfo exists $win]} { wm deiconify $win ; raise $win ; return }
    global help config check makeVar label
    toplevel $win -class Obeah
    wm minsize $win 1 1
    if {$edit != {}} {
	wm title $win "Edit $txt \"$label($edit)\""
    } {  
	wm title $win "New $txt"
    }
    set config(!${frm}def) {}
    set config(!${frm}check) {}
    set config(!${frm}make) {}
    set config(!${frm}help) {}
    if {$edit != {}} {
	set config(!${frm}label) $label($edit)
	set config(!${frm}def) $config($edit)
	if {[info exists check($edit)]} {
	    set config(!${frm}check) $check($edit)
	}
	if {[info exists makeVar($edit)]} {
	    set config(!${frm}make) $makeVar($edit)
	}
	if {[info exists help($edit)]} {
	    set config(!${frm}help) $help($edit)
	}
    }
    set label(!${frm}label) Label
    set label(!${frm}def) {Default Value}
    set label(!${frm}make) {Make Variable}
    set label(!${frm}check) {Check}
    set label(!${frm}help) {Help String}
    ob_LabelEntry !${frm}label $win.name -width 15
    ob_LabelEntry !${frm}def $win.def -width 15
    ob_LabelEntry !${frm}make $win.mkv -width 15
    ob_LabelEntry !${frm}check $win.chk -width 15
    ob_LabelEntry !${frm}help $win.help -width 15
    ob_nextBind $win.name $win.def
    ob_nextBind $win.def $win.mkv
    ob_nextBind $win.mkv $win.chk
    ob_nextBind $win.chk $win.help
    ob_nextBind $win.help $win.name
    pack $win.name $win.def $win.mkv $win.chk $win.help -fill x
    frame $win.ctl
    button $win.ctl.ok -text Dismiss -command "destroy $win"
    bind $win.ctl.ok <Any-Enter> "[bind Button <Any-Enter>]
ob_showHelp !${frm}ok"
    button $win.ctl.apply -text Apply \
      -command "obc_doField $frm $prc {$edit} ; destroy $win"
    bind $win.ctl.apply <Any-Enter> "[bind Button <Any-Enter>]
ob_showHelp !${frm}apply"
    button $win.ctl.delete -text Delete \
      -command "obc_delField {$edit} ; destroy $win"
    bind $win.ctl.delete <Any-Enter> "[bind Button <Any-Enter>]
ob_showHelp !${frm}delete"
    pack $win.ctl.ok $win.ctl.apply $win.ctl.delete \
      -fill x -expand 1 -side left
    pack $win.ctl -fill x
}
#
proc obc_load {} { ob_load }
#
proc ob_load {} {
    global config help check action makeVar default label window obeah delete
    wm withdraw .
    catch {destroy .conf .msg .help .ctl}
    foreach x {config help check action makeVar default label window} {
	foreach v [array names $x] {
	    if {![string match {!*} $v]} { unset ${x}($v) }
	}
    }
    unset delete
    ob_makeArray delete
    set obeah(program) {}
    set obeah(makefile) {}
    set obeah(cfProg) configure
    set prcs [info procs]
    if {![file exist $obeah(cfFile)]} {
	ob_tellError "File \"$obeah(cfFile)\" does not exist."
	if {!$obeah(cMode)} { exit 1 }
    } \
    elseif {[catch {source $obeah(cfFile)} msg]} {
	ob_tellError "Error in config file \"$obeah(cfFile)\" : $msg"
	if {!$obeah(cMode)} { exit 1 }
    }
    set obeah(procs) {}
    foreach x [info procs] {
	if {[lsearch $prcs $x] < 0} { lappend obeah(procs) $x }
    }
    if {$obeah(program) == {}} {
	if {!$obeah(cMode)} {
	    ob_tellError {No program name specified in configuration file.}
	    exit 1
	}
	set obeah(program) [string tolower [file tail [pwd]]]
    }
    if {$obeah(makefile) == {}} { set obeah(makefile) $obeah(program).mk }
    set obeah(altered) 0
    ob_configWindow
    wm deiconify .
}
#
proc obc_doControl {fname} {
    global action help window label config
    if {[set name $fname] == {}} {
	set l [winfo children .ctl]
	if {[regexp {^\.ctl\.b([0-9]*)} \
	  [lindex $l [expr [llength $l] - 1]] m name]} {
	    incr name
	    set name "b${name}"
	} {
	    set name b0
	}
    }
    set label($name) $config(!clabel)
    set action($name) $config(!caction)
    set help($name) $config(!chelp)
    if {[info exists window($name)]} {
	$window($name) configure -text $label($name) -command $action($name)
    } {
	button .ctl.$name -text $label($name) -command $action($name)
	bind .ctl.$name <Any-Enter> "[bind Button <Any-Enter>]
ob_showHelp $name"
	bind .ctl.$name <Shift-1> "obc_control $name"
	pack .ctl.$name  -fill x -before .ctl.help -side left
	set window($name) .conf.$name
    }
    ob_changed
}
#
proc obc_delControl {edit} {
    global action label window delete config
    if {$edit == {}} { set edit [string trim $config(!flabel)] }
    if {[winfo exists window($edit)]} {
	catch {destroy $window($fname)}
	catch {unset action($fname) label($fname) window($fname)}
    } \
    elseif {[string match {!*} $edit]} {
	set delete($edit) 1
	destroy .ctl.[string range $edit 1 end]
    }
    ob_changed
}
#
proc obc_control {args} {
    if {[winfo exists .control]} {
	wm deiconify .control
	raise .control
	return
    }
    global help action label config
    toplevel .control -class Obeah
    wm minsize .control 1 1
    set edit [lindex $args 0]
    if {[set bin [string match {!*} $edit]]} {
	set lab \
	  [string toupper [string range $edit 1 1]][string range $edit 2 end]
	set t "Edit control \"$lab\""
    } \
    elseif {$edit != {}} {
	set t "Edit control \"$label(edit)\""
    } {  
	set t {New control}
    }
    wm title .control $t
    if {$bin} {
	set config(!clabel) $lab
	set config(!caction) "ob_[set ln [string range $edit 1 end]]"
	set config(!chelp) $help(!$ln)
    } \
    elseif {$edit != {}} {
	set config(!clabel) $label($edit)
	if {[info exists action($edit)]} {
	    set config(!caction) $action($edit)
	}
	if {[info exists help($edit)]} {
	    set config(!chelp) $help($edit)
	}
    }
    set label(!clabel) Label
    set label(!caction) Action
    set label(!chelp) {Help String}
    ob_LabelEntry !clabel .control.name -width 15
    ob_LabelEntry !caction .control.act -width 15
    ob_LabelEntry !chelp .control.help -width 15
    ob_nextBind .control.name .control.act
    ob_nextBind .control.act .control.help
    ob_nextBind .control.help .control.name
    pack .control.name .control.act .control.help -fill x
    frame .control.ctl
    button .control.ctl.cancel -text Dismiss -command {destroy .control}
    bind .control.ctl.cancel <Any-Enter> "[bind Button <Any-Enter>]
ob_showHelp !ccancel"
    button .control.ctl.ok -text Apply \
      -command {obc_doControl {$edit} ; destroy .control}
    bind .control.ctl.ok <Any-Enter> "[bind Button <Any-Enter>]
ob_showHelp !cok"
    if {$bin} { .control.ctl.ok configure -state disabled }
    button .control.ctl.delete -text Delete \
	-command "obc_delControl {$edit} ; destroy .control"
    bind .control.ctl.delete <Any-Enter> "[bind Button <Any-Enter>]
ob_showHelp !cdelete"
    pack .control.ctl.cancel .control.ctl.ok .control.ctl.delete \
      -fill x -expand 1 -side left
    pack .control.ctl -fill x
}
#
proc obc_makeCreate {} {
    global help config check makeVar label obeah
    set help(!program) {The name of the program being configured.} 
    toplevel .create -class Obeah
    wm minsize .create 1 1
    wm title .create "Obeah Script Creation"
    set label(!program) {Program Name}
    set label(!config) {Config File}
    set label(!cprog) {Config Program}
    set label(!cmakefile) {Makefile Name}
    ob_LabelEntry !program .create.prog -width 15
    .create.prog.entry configure -textvariable obeah(program)
    ob_LabelEntry !config .create.cfile -width 15
    .create.cfile.entry configure -textvariable obeah(cfFile)
    ob_LabelEntry !cprog .create.cprog -width 15
    .create.cprog.entry configure -textvariable obeah(cfProg)
    ob_LabelEntry !cmakefile .create.mfile -width 15
    .create.mfile.entry configure -textvariable obeah(makefile)
    ob_nextBind .create.prog .create.cfile
    ob_nextBind .create.cfile .create.cprog
    ob_nextBind .create.cprog .create.mfile
    ob_nextBind .create.mfile .create.prog
    frame .create.ctl
    set help(!program) {The name of the program to be configured.}
    set help(!config) {The name of the file containing configuration information created using the Save button.}
    set help(!cprog) {The name of the configuration program created using the Program button.}
    set help(!cmakefile) {The name of the file containing the make commands for the program being configured.}
    set help(!bexit) {Clicking the Exit button will exit the configuration program.}
    set help(!bload) {Clicking the Load button will load the file named in the configuration file field.}
    set help(!bsave) {Clicking the Save button will make a configuration file.}
    set help(!bfield) {Clicking the Field button will allow you to add another configurable field.}
    set help(!binvisible) {Clicking the Invisible button will allow you to \
add an invisible field i.e. a value that is passed to make but is not configurable.}
    set help(!bcontrol) {Clicking the Control button will allow you to add another control button.}
    set help(!bprogram) {Clicking the Program button will create a cutdown version of obeah that can be distributed as a configuration program.}
    set help(!fok) {Close the field creation/editting window.}
    set help(!fapply) {Create the new field or apply the changes.}
    set help(!fdelete) {Delete the field.}
    set help(!iok) {Close the invisible field creation/editting window.}
    set help(!iapply) {Create the new invisible field or apply the changes.}
    set help(!idelete) {Delete the invisible field.}
    set help(!ccancel) {Close the control creation/editting window.}
    set help(!cok) {Create the new control or apply any changes.}
    set help(!cdelete) {Delete the control.}
    set help(!flabel) {The Label displayed for the field.}
    set help(!fdef) {The default value for the field.}
    set help(!fmake) {The make variable that holds the fields value.}
    set help(!fcheck) {Code executed to verify the value entered by the user.}
    set help(!fhelp) {The help string displayed for this field.}
    set help(!ilabel) {The Label displayed for the Invisible field (-c mode only).}
    set help(!idef) {The default value for the field.}
    set help(!imake) {The make variable that holds the fields value.}
    set help(!icheck) {Code executed to verify the value entered by the user.}
    set help(!ihelp) {The help string displayed for this field (-c mode only).}
    set help(!clabel) {The label displayed on the control.}
    set help(!caction) {The action that happens when the control is clicked.}
    set help(!chelp) {The help string displayed for the control.}
    foreach x {Exit Load Save Field Invisible Control Program} {
	set lx [string tolower $x]
	button .create.ctl.$lx -text $x -command obc_$lx -width 10
	bind .create.ctl.$lx <Any-Enter> "[bind Button <Any-Enter>]
ob_showHelp !b$lx"
	pack .create.ctl.$lx -side left -fill x -expand 1
    }
    .create.ctl.save configure -state disabled
    pack .create.prog .create.cfile .create.cprog .create.mfile -fill x
    pack .create.ctl -fill x
}
#
proc ob_main {argv} {
    global config help check makeVar action default label delete obeah

    ob_makeArray window config help check makeVar action default \
      label delete obeah
#
    set obeah(version) 1.1
    set obeah(cMode) 0
    if {[lindex $argv 0] == {-c}} {
	set obeah(cMode) 1
	set argv [lrange $argv 1 end]
    }
    set obeah(verified) -1
    set obeah(helpOn) 0
#
    set obeah(cfFile) configure.in
    set obeah(altered) 0
    bind Entry <Any-KeyPress> {+ ob_changed}
    bind Entry <Delete>  {+ ob_changed}
    bind Entry <BackSpace>  {+ ob_changed}
    bind Entry <Control-h>  {+ ob_changed}
    bind Entry <Control-d>  {+ ob_changed}
    bind Entry <Control-u>  {+ ob_changed}
    bind Entry <Control-v>  {+ ob_changed}
    bind Entry <Control-w>  {+ ob_changed}
    if {$argv != {}} {
	set obeah(cfFile) [lindex $argv 0]
	set argv [lrange $argv 1 end]
    }
    ob_load
    if {$obeah(cMode)} { obc_makeCreate }
}
#
ob_main $argv
