# dbentries.tcl -- Ray R. Larson (mar 92)
# Create a "entry" style display box from the data stored in a
# tuplearray. Takes two arguments.  The first is the global tuplearray name.
# The second is a set of arguments for use in creating the message
# to be displayed in the message box area of the form.

proc mkEntry {{tuple "junk"} {msgArgs {-text "Postgres Entry Form"}}} {
    if {[string compare "$tuple" "junk"] == 0} {error "mkEntry requires an tuplearray name"}
    set w [format ".%s_ENTRY" $tuple]
    catch {destroy $w}
    toplevel $w
    global $tuple group$tuple tuple$tuple

    set group$tuple 0
    set tuple$tuple 0
    set tgroups [set [set tuple](GROUPS)]
    set gtuples [set [set tuple](TUPLES.0)]

    # Create three frames in the main window. The top frame will hold the
    # message and the bottom one will hold the <next> & <quit> buttons.
    # The middle frame holds the labels and data elements of the
    # instances of the retrieved tuples from the tuplearray. Arrange them
    # one above the other, with any extra vertical space split between
    # them.

    frame $w.top -relief raised -border 1
    frame $w.mid -relief raised -border 1
    frame $w.bot -relief raised -border 1
    pack append $w $w.top {top fill expand} $w.mid {top fill expand} $w.bot {top fill expand}

    # Create the message widget and arrange for it to be centered in the
    # top frame.

    eval message $w.top.msg -justify center \
	    -font -*-times-medium-r-normal--*-180* -aspect 500 $msgArgs
    frame $w.top.lframe -borderwidth 1
    pack append $w.top.lframe \
         [label $w.top.lframe.gr -text "Groups = $tgroups" -relief raised] \
              {left frame w padx 5 pady 2 expand}  \
         [label $w.top.lframe.tu -text "Tuples = $gtuples" -relief raised] \
              {left frame w padx 5 pady 2 expand}

    pack append $w.top $w.top.msg {top expand padx 5 pady 5} \
         $w.top.lframe {top expand padx 2 pady 2}

    # create frames for each attribute of the tuple having a
    # label for the attribute name and an entry containing the
    # value of the attribute
    set fldnames [set [set tuple](FIELDS.0)]
    foreach f $fldnames {
        frame $w.mid.$f -relief raised -border 1
        label $w.mid.$f.lab -text "$f" -relief raised  \
              -font -*-times-medium-r-normal--*-180*
        set n [lsearch $fldnames $f]
        set fldval [lindex [set [set tuple](0.0)] $n]
        entry $w.mid.$f.entry -relief sunken
        scrollbar $w.mid.$f.scroll -relief sunken -orient horiz \
              -command "$w.mid.$f.entry view"
        pack append $w.mid.$f $w.mid.$f.lab {left pady 2} \
                $w.mid.$f.entry {right expand fillx pady 2} \
                $w.mid.$f.scroll {top fillx}
        pack append $w.mid $w.mid.$f {top expand padx 2}
        bind.entry $w.mid.$f.entry
        $w.mid.$f.entry config -scroll "$w.mid.$f.scroll set"
        $w.mid.$f.entry insert 0 "$fldval"
    }

    # Create the buttons as needed and arrange them from left to right
    # in the bottom frame.  Embed the "Next Item" button in an additional sunken
    # frame to indicate that it is the default button, and arrange for that
    # button to be invoked as the default action for clicks and returns in
    # the dialog.

	frame $w.bot.nexti -relief sunken -border 1
	pack append $w.bot $w.bot.nexti {left expand padx 20 pady 20}
	button $w.bot.nexti.button -text "Next Item" \
		-command "d.nextentrytuple $tuple +1"
	pack append $w.bot.nexti $w.bot.nexti.button {expand padx 12 pady 12}
	bind $w.top <Enter> "$w.bot.nexti.button activate"
	bind $w.top.msg <Enter> "$w.bot.nexti.button activate"
	bind $w.bot <Enter> "$w.bot.nexti.button activate"
	bind $w.top <Leave> "$w.bot.nexti.button deactivate"
	bind $w.top.msg <Leave> "$w.bot.nexti.button deactivate"
	bind $w.bot <Leave> "$w.bot.nexti.button deactivate"
	bind $w <1> "$w.bot.nexti.button config -relief sunken"
	bind $w <ButtonRelease-1> \
		"d.formnexttuple $tuple 1 ; $w.bot.nexti.button deactivate"
	bind $w <Return> "d.nextentrytuple $tuple +1"
        focus $w

        if {[set [set tuple](GROUPS)] > 1} {
            button $w.bot.nextg -text "Next Group" -command "d.nextentrygroup $tuple"
	    pack append $w.bot $w.bot.nextg {left expand padx 20}
	}
        button $w.bot.prev -text "Previous Item" -command "d.nextentrytuple $tuple -1"
        button $w.bot.quit -text "Quit" -command "destroy $w"
	pack append $w.bot $w.bot.prev {left expand padx 20} \
               $w.bot.quit {left expand padx 20}

}

#
# procedure to display the next or previous entry in a form
#
proc d.nextentrytuple {tuple {next +1}} {
    set w [format ".%s_ENTRY" $tuple]
    global $tuple group$tuple tuple$tuple

    set tgroups [set [set tuple](GROUPS)]
    set groupn  $group$tuple
    set gtuples [set [set tuple](TUPLES.$groupn)]
    set nexttuple [expr {[set tuple$tuple] + $next}]
    if {$nexttuple < 0} {set nexttuple 0}
    if {$nexttuple > $gtuples} {set nexttuple [expr {$gtuples - 1}]}
    set tuple$tuple $nexttuple
    set fldnames [set [set tuple](FIELDS.$groupn)]

    # will need to add things to preserve and update old info in
    # the database - just displays now.

    foreach f $fldnames {
        set n [lsearch $fldnames $f]
        set fldval [lindex [set [set tuple]($groupn.$nexttuple)] $n]
        $w.mid.$f.entry delete 0 end
        $w.mid.$f.entry insert end "$fldval"
    }
 }

