#!/usr/pkg/bin/wish
#
# Version 1.1 Patch 7
#
# ----------------------------------------------------------------------
#   AUTHOR:  Lindsay Marshall <lindsay.marshall@newcastle.ac.uk>
# ----------------------------------------------------------------------
# Copyright 1994 The University of Newcastle upon Tyne (see COPYRIGHT)
# ======================================================================
#
#
# Category manipulation procs
#
proc Category {name args} {
    global actParent
    eval Action $name $args
    $name configure -parent root
}
#
# Action code
#
proc Action {name args} {
    global actTitle actText actDone actDue actStart actEnd actParent \
      actEntered actActions actLabel actBegin actLevel actType zorro
    if {$name == {::}} {
	return [eval Action_[lindex $args 0] [lrange $args 1 end]]
    }
    set actType($name) $zorro(defaultType)
    set actTitle($name) {}
    set actText($name) {}
    set actDone($name) 0
    set actDue($name) {}
    set actStart($name) {}
    set actEnd($name) {}
    set actParent($name) {}
    set actEntered($name) {}
    set actActions($name) {}
    set actLabel($name) {}
    set actBegin($name) {}
    set actLevel($name) 0
    eval action_configure $name $args
    proc $name {op args} "return \[eval action_\$op $name \$args\]"
    return $name
}
#
proc Action_new {catg} {
    global cntActions
    if {$catg != {nil}} {
	set v [Action b$cntActions -parent $catg -entered [today]]
	incr cntActions
	$v edit
    }
}
#
proc Action_create {lvl} { Action_new [Action_selection $lvl] }
#
proc Action_clone {catg} {
    global cntActions actLevel cntActions zorro
    if {[set v [Action :: selection [expr $actLevel($catg) + 1]]] != {nil}} {
	set n $cntActions
	incr cntActions
	[$v clone d$n " $zorro(copyTag)"] display
	$catg addAction d$n
	$catg adjust
    }
}
#
proc action_clone {this name tag} {
    global actActions cntActions
    proc $name {op args} "return \[eval action_\$op $name \$args\]"
    foreach x [info globals act*] {
	global $x
	set ${x}($name) [set ${x}($this)]
    }
    set s $actActions($name)
    set actActions($name) {}
    foreach x $s {
	if [string match new* $x] continue
	set n $cntActions
	incr cntActions
	$name addAction [$x clone d$n {}]
    }
    append actTitle($name) $tag
    return $name
}
#
proc Action_sort {actions sortBy} {
    global actTitle actParent actDone actDue actEntered actBegin
    set lst {}
    foreach x $actions {
	set key {}
	foreach fn $sortBy {
	    switch $fn {
	    priority  { lappend key [$x priority]}
	    title { lappend key $actTitle($x) }
	    parent -
	    category { lappend key [$actParent($x) title]}
	    done { lappend key $actDone($x) }
	    begin { lappend key $actBegin($x) }
	    due { lappend key $actDue($x) }
	    entered { lappend key $actEntered($x) }
	    }
	}
	lappend lst [list $key $x]
    }
    return [lsort $lst]
}
#
proc action_sort {this sortBy} {
    global actActions
    return [Action :: sort $actActions($this) $sortBy]
}
#
proc Action_selection {level} {
    global selectAction
    if {[set x [lindex $selectAction $level]] == {}} { set x nil }
    return $x
}
#
proc Action_setSelection {level name} {
    global selectAction zorro
    if {[set sel [Action :: selection $level]] == $name} return
    while {[llength $selectAction] <= $level} {	lappend selectAction {} }
    set selectAction [lreplace $selectAction $level $level $name]
    $sel doUnselect
    $name doSelect
}
#
proc action_showWindow {this} {
    global zorro
    if ![ winfo exists [set t [$this toplevel]]] {
	toplevel $t
	frame $t.f1
	pack $t.f1 -fill both -expand 1
	wm title $t [$this label]
	wm minsize $t 1 1 
    }
    $this show $t.f1 $zorro(sortOrder)
}
#
proc action_show {this win sortBy} {
    global zorro actLevel
    set aw [$this build $win]
    if {$zorro(newStyle) == {listItem}} {
	set lvl [expr $actLevel($this) + 1]
	Action new$lvl -category $this -title *NEW*
    }
    foreach x [set lst [$this sort $sortBy]] { [lindex $x 1] display }
    set x nil
    if {$lst != {} && $actLevel($this) < $zorro(levels) - 1} {
	if [string match new* [set x [lindex [lindex $lst 0] 1]]] {
	    if {[set x [lindex [lindex $lst 1] 1]] == {}} { set x nil }
	}
    }
    Action :: setSelection [expr $actLevel($this) + 1] $x
    $this adjust
}
#
proc action_toplevel {this} {
    global actLevel zorro actParent
    if {$actLevel($this) > $zorro(levels)} {
	return ._$actParent($this)
    }
    return .@todo
}
#
proc action_window {this} {
    global actLevel
    return [$this toplevel].f1.$actLevel($this).list.l.frame.$this
}
#
proc cscroll {win p1 p2} {
    set flg [winfo ismapped $win]
    if {$p1 != 0 || $p2 != 1} {
	if !$flg { pack $win -side right -fill y }
	$win set $p1 $p2
    } \
    elseif $flg { pack forget $win }
}
#
proc action_resize {this win wd ht} {
    global zorro
    set fw [winfo width $win.frame]
    set fh [winfo height $win.frame]
    if $zorro(shrink) {
	if {$wd > $fw } { $win configure -width $fw }
    }\
    elseif {$wd > $fw} { $win.frame configure -width $wd  }
    if {$fh < $fw && [winfo ismapped [winfo parent $win].v]} {
	pack forget [winfo parent $win].v
    }
}
#
proc action_build {this f} {
    global zorro actLevel actTitle actParent
    set f $f.[expr $actLevel($this) + 1]
    $f.label configure -text [$this label]
    return $f.list.l
}
#
proc action_label {this} {
    global actTitle actLabel zorro
    if {$actLabel($this) != {}} { return $actLabel($this) }
    return "$actTitle($this) $zorro(subLabel)"
}
#
proc action_title {this} {
    global actTitle
    return $actTitle($this)
}
#
proc action_actions {this} {
    global actActions
    return $actActions($this)
}
#
proc action_addAction {this action} {
    global actActions actDone
    if {[lsearch $actActions($this) $action] < 0} {
	lappend actActions($this) $action
	set actDone($this) 0
	$this doneDisplay
    }
}
#
proc action_removeAction {this action} {
    global actActions
    if {[set x [lsearch $actActions($this) $action]] >= 0} {
	set actActions($this) [lreplace $actActions($this) $x $x]
	set actDone($this) 0
	$this doneDisplay
    }
}
#
proc action_priority {this} {
    global actStart actEnd actActions zorro
    if {$actStart($this) != {}} { return $actStart($this) }
    if {$actEnd($this) == {} && $actActions($this) != {}} {
	set mx {}
	foreach x $actActions($this) {
	    set v [$x priority]
	    if {$mx == {} || ($v != {} && $v < $mx)} { set mx $v }
	}
	return $mx
    }
    return $actEnd($this)
}
#
proc action_askDel {this args} {
    global actParent actTitle
    set cat $actParent($this)
    $this kill [ask {Delete Action} \
      "Are you sure you want to delete [$cat label] \"$actTitle($this)\"?"]
}
#
proc action_saveAs {this desc name catg} {
    global actTitle actText actDone actDue actStart actEnd actParent \
      actEntered actBegin actLabel actActions
    if [string match new* $this] { return }
    puts -nonewline $desc "Action $name -parent $catg"
    if {$actDone($this) != 0} {
	puts -nonewline $desc " \\\n  -done $actDone($this)"
    }
    foreach x {Label Title Text Begin Due Start End Entered} {
    	if {[set v [set act${x}($this)]] != {}} {
	    puts -nonewline $desc \
	      " \\\n  -[string tolower $x] \"[clean [set act${x}($this)]]\""
	}
    }
    puts $desc {}
    set sc 0
    foreach x $actActions($this) {
	$x saveAs $desc ${name}a${sc} $name
	incr sc
    }
}
#
proc action_flag {this fg} {
    global actLevel actParent actDone
    if [winfo exists [set f [$this window]]] {
	set ft $f.title
	$ft configure -foreground $fg
	if [winfo exists $f.done] {
	    $f.done.db itemconfigure all -outline $fg
	    if $actDone($this) {
	        $f.done.db itemconfigure all -fill $fg
	    } {
		$f.done.db itemconfigure ovl -fill {}
		$f.done.db itemconfigure arc -fill $fg
	    }
	}
	if [winfo exists $f.prio] { $f.prio configure -foreground $fg }
    }
}
#
proc action_mark {this rel} {
    global actLevel actParent actDone
    if [winfo exists [set f [$this window]]] { $f configure -relief $rel }
}
#
proc action_doUnselect {this} {
    global actLevel zorro
    set x [set lvl [expr $actLevel($this) + 1]]
    while {$x <= $zorro(maxlevel)} {
	Action :: setSelection $x nil
	incr x
    }
    $this mark flat
    set x $lvl
    while {[winfo exists .@todo.f1.$x.list.l.frame]} {
	catch "destroy [winfo children .@todo.f1.$x.list.l.frame]"
	.@todo.f1.$x.list.l.frame configure -height 0
	.@todo.f1.$x.label configure -text $zorro(subLabel)
	incr x
    }
}
#
proc action_doneClick {this} {
    global zorro actLevel
    set lvl $actLevel($this)
    if {[Action :: selection $lvl] != $this} {
	Action :: setSelection $lvl $this
    } {
	$this doneToggle 0
    }
}
#
proc action_doSelect {this} {
    global zorro actLevel
    if [string match new* $this] return
    set lvl $actLevel($this)
    $this mark raised
    if {$lvl < $zorro(levels)} { $this show .@todo.f1 $zorro(sortOrder) }\
    elseif {$lvl < $zorro(maxlevel)} { $this showWindow }
}
#
proc action_unstash {this} {
    global stash stashdue
    set x $stash($this)
    foreach y [lsort [info globals act*]] {
	global $y
	set ${y}($this) [lindex $x 0]
	set x [lrange $x 1 end]
    }
    unset stash($this) stashdue($this)
}
#
proc action_stash {this} {
    global stash stashdue actDue
    set stash($this) {}
    foreach x [lsort [info globals act*]] {
	global $x
	lappend stash($this) [set ${x}($this)]
    }
    set stashdue($this) $actDue($this)
}
#
proc action_set {this} {
    global zorro actTitle actStart actEnd actParent actDue \
      stash stashdue dayVar mthVar mthIndex yearVar actLevel
    if {[set actTitle($this) [string trim $actTitle($this)]] == {}} {
	warn {You must provide a title for an action!}
	return 0
    }
    set d $stashdue($this)
    set win .$this.due
    set actDue($this) \
      [format "%04d/%02d/%02d" $yearVar($win) $mthIndex($win) $dayVar($win)]
    set t [today]
    if {$d == {} && $actDue($this) == $t} { set actDue($this) {}}
    if {$actDue($this) != {} && $actDue($this) < $t && ![ask {Date Correction?} \
      {Your completion date is passed! Do you want this to stand?}]} {
	return 0
    }
    if {$actStart($this) != {} && $actDue($this) == {}} {
	warn \
	  {You must provide a completion date if you use variable priorities!}
	return 0
    }
    unset stash($this) stashdue($this) mthVar($win) mthIndex($win) \
      dayVar($win) yearVar($win)
    set actStart($this) [pValue $actStart($this)]
    set actEnd($this) [pValue $actEnd($this)]
    $this configure -text [.$this.text get 1.0 end]
    set lvl $actLevel($this)
    if {$actParent($this) != \
      [Action :: selection $actLevel($actParent($this))]} {
	$this undisplay
    } \
    elseif ![winfo exists [set f [$this window]]] {
	$this display
	Action :: setSelection $lvl $this
	$actParent($this) adjust
    } {
	if {[set prio [$this priority]] != {}} {
	    $this flag [pFground $prio]
	    if $zorro(priorities) { $f.prio configure -text " [pName $prio] " }
	}
    }
    return 1
}
#
proc action_undisplay {this} {
    global actLevel
    set win [$this window]
    if [winfo exists $win] {
	set w [winfo parent $win]
	set ht [winfo reqheight $win]
	destroy $win
	$w configure -height [expr {[winfo reqheight $w] - $ht}]
	if {$this == [Action :: selection $actLevel($this)]} {
	    Action :: setSelection $actLevel($this) nil
	}
    }
}
#
proc action_delete {this} {
    global actParent actActions
    if [string match new* $this] return
    foreach x $actActions($this) { $x delete }
    set cat $actParent($this)
    $this undisplay
    foreach x [info globals act*] {
	global $x
	catch {unset ${x}($this)}
    }
    $cat removeAction $this
    rename $this {}
}
#
proc action_configure {this args} {
    global actTitle actText actDone actDue actStart actEnd \
      actParent actEntered actLabel actBegin actLevel
    while {$args != {}} {
	switch -exact -- [lindex $args 0] {
	-title { set actTitle($this) [string trim [lindex $args 1]] }
	-label { set actLabel($this) [string trim [lindex $args 1]] }
	-text { set actText($this) [lindex $args 1] }
	-done { set actDone($this) [lindex $args 1] }
	-due { set actDue($this) [lindex $args 1] }
	-begin { set actBegin($this) [lindex $args 1] }
	-start { set actStart($this) [lindex $args 1] }
	-end { set actEnd($this) [lindex $args 1] }
	-entered { set actEntered($this) [lindex $args 1] }
	-category -
	-parent {
		if {[set ncg [lindex $args 1]] != \
		  [set cg $actParent($this)]} {
		    if {$cg != {}} {
			$cg removeAction $this
			if {[Action :: selection $actLevel($this)] == $cg} {
			    catch {destroy [$this window]}
			}
		    }
		    $ncg addAction $this
		    set actParent($this) $ncg
		    set actLevel($this) [expr $actLevel($ncg) + 1]
		}
	    }
	}
	set args [lrange $args 2 end]
    }
}
#
proc action_print {this} {
    global actTitle actDone zorro
    if {[set done $actDone($this)] && !$zorro(showDone)} { return }
    puts stdout "[$this priority] $actTitle($this)"
}
#
proc action_doneDisplay {this} {
    global actDone actActions zorro
    set f [$this window]
    if {$this == {root} || ![winfo exists $f] || [string match new* $this]} {
	return
    }
    set fg [$f.title cget -foreground]
    append f .done
    catch {$f.db delete all}
    set num [llength $actActions($this)]
    if {$zorro(newStyle) == {listItem}} { incr num -1 }
    set type oval
    set fill {}
    if $actDone($this) {
	set fill $fg
    } \
    elseif {$num > 0} {
	set dn 0
	foreach x $actActions($this) { if $actDone($x) { incr dn } }
	if {$dn == $num} {
	    set actDone($this) 1
	    set fill $fg
	} \
	elseif {$dn != 0} {
	    set actDone($this) 0
	    $f.db create arc 5 2 15 12 -start 90 \
	      -extent [expr 360 * $dn / $num] -fill $fg -tag arc
	}
    }
    $f.db create $type 5 2 15 12 -outline $fg -fill $fill -tag ovl
}
#
proc action_doneFlag {this} {
    global actDone actActions actParent zorro
    set prnt $actParent($this)
    if !$actDone($this) {
	set num [llength $actActions($this)]
	if {$zorro(newStyle) == {listItem}} { incr num -1 }
	if {$num > 0} { set actDone($this) 1 }
    } {
	foreach x $actActions($this) { $x doneToggle 0}
    }
    $this doneDisplay
    $prnt doneDisplay
}
#
proc action_doneToggle {this doit} {
    global actDone actActions actParent zorro
    if [string match new* $this] return
    set prnt $actParent($this)
    set actDone($prnt) 0
    if $actDone($this) {
	set num [llength $actActions($this)]
	if {$zorro(newStyle) == {listItem}} { incr num -1 }
	if {$num <= 0 || $doit} {
	    set actDone($this) 0
	    foreach x $actActions($this) { $x doneToggle $doit}
	}
    } {
	set actDone($this) 1
	foreach x $actActions($this) { $x doneToggle $doit}
    }
    $this doneDisplay
    $prnt doneDisplay
}
#
proc action_doneButton {this win fg bg} {
    global actDone actActions
    set f [frame $win -background $bg]
    canvas $f.db -background $bg -width 17 -height 14 \
      -highlightthickness 0
    $this doneDisplay
    bind $f.db <1> "$this doneClick"
    bind $f.db <Shift-1> "$this doneToggle 1"
    pack $f.db -fill both
    return $win
}
#
proc action_adjust {this} {
    global actLevel zorro
    update
    set win .@todo.f1.[expr $actLevel($this) + 1].list.l
    if {$zorro(shrink)} {
	set ht [winfo reqheight $win]
	set fht [winfo reqheight $win.frame]
	if {$fht < $ht} { $win configure -height $fht }
	set ht [winfo reqwidth $win]
	set fht [winfo reqwidth $win.frame]
	if {$fht < $ht} { $win configure -width $fht }
    } \
    elseif {[set k [winfo children $win.frame]] != {}} {
	set ht [expr [set fht [winfo reqheight [lindex $k 0]]] * [llength $k]]
	set cwd [winfo reqwidth $win.frame]
	set cht $ht
	$win conf -scrollregion [list 0 0 $cwd $cht] -yscrollincrement $fht
	$win.frame configure -height $ht
    }
}
#
proc action_display {this} {
    global actTitle actDone zorro actStart actEnd actParent actLevel
    if {[set done $actDone($this)] && !$zorro(showDone)} { return }
    if [winfo exists [set f [$this window]]] return
    set prio [$this priority]
    set fg [pFground $prio]
    set bg [pBground $prio]
    frame $f -background $bg -borderwidth 2 -relief flat
    entry $f.title -relief flat -textvariable actTitle($this) \
      -foreground $fg -background $bg -highlightthickness 0
    if !$zorro(fastEdit) {
	bindtags $f.title $f.title
	$f.title configure -state disabled
	$f.title configure -cursor [$f cget -cursor]
    }
    if $zorro(doneFlag) {
	pack [$this doneButton $f.done $fg $bg] -side left
    }
    if $zorro(priorities) {
	pack [label $f.prio -anchor w -text " [pName $prio] " \
	  -foreground $fg -background $bg] -side left
	bind $f.prio <1> "Action :: setSelection $actLevel($this) $this ; break"
	bind <Double-Button-1> $f.prio "$this edit ; break"
    }
    pack $f.title -side left -fill x -expand 1
    if [string match new* $this] {
	bind $f.title <1> { }
	bind $f.title <Double-Button-1> "Action :: new $actParent($this)"
    } {
	bind $f.title <1> "Action :: setSelection $actLevel($this) $this ; break"
	bind $f.title <Double-Button-1> "$this edit ; break"
    }
    bind $f.title <B1-Motion> { }
    bind $f.title <Shift-B1-Motion> { }
    bind $f.title <2> { }
    bind $f.title <B2-Motion> { }
    set lvl $actLevel($this)
    set np [$this toplevel].f1.$lvl.list.l.frame.new$lvl
    if {[winfo exists $np] && $np != $f} {
	pack $f -anchor w -fill x -expand 1 \
	  -before [$this toplevel].f1.$lvl.list.l.frame.new$lvl
    } {
	pack $f -anchor w -fill x -expand 1
    }
    return $this
}
#
proc action_buttonState {this win} {
    global actStart actEnd zorro
    if {$win == ".$this.pri"} {
	if {[set x [expr [pIndex $actEnd($this)] + 1]] > 0} {
	    for {set i 0} {$i < $x} { incr i} {
		.$this.spri.$i configure -state disabled
	    }
	    set l [llength $zorro(priorityLabels)]
	    for {set i $x} {$i < $l} { incr i} {
		.$this.spri.$i configure -state normal
	    }
	    if {[pIndex $actStart($this)] < $x && $actStart($this) != {}} {
		set actStart($this) [lindex $zorro(priorityLabels) $x]
	    }
	} {
	    set actStart($this) {}
	}
    }
}
#
proc action_priorityButtons {this win label var} {
    global zorro
    frame $win
    label $win.label -text $label -width 15 -anchor w
    pack $win.label -side left
    set idx 0
    foreach x $zorro(priorityLabels) {
	radiobutton $win.$idx -variable ${var}($this) -value $x \
	  -relief flat -text $x -command "$this buttonState $win"
	pack $win.$idx -side left -expand 1
	incr idx
    }
    pack [label $win.plab -text Value:] -side left -padx 5
    entry $win.entry -textvariable ${var}($this) -relief sunken
    pack $win.entry -fill x -side left -expand 1
}
#
proc action_showStart {this} {
    global tactPVar actStart actEnd zorro
    if $tactPVar($this) {
	if {[set x [expr [pIndex $actEnd($this)] + 1]] > 0} {
	    set actStart($this) [lindex $zorro(priorityLabels) $x]
	} {
	    set actStart($this) {}
	}
	for {set i 0} {$i < $x} { incr i} {
	    .$this.spri.$i configure -state disabled
	}
    	pack .$this.spri -after .$this.pri
    } {
    	set actStart($this) {}
    	pack forget .$this.spri -fill x -padx 5 -pady 5
    }
}
#
proc popup {win} {
   wm deiconify $win
   raise $win
}
#
proc action_edit {this} {
    global actTitle actText actDone actStart actEnd actDue zorro \
      tactPVar actDue actLabel actParent actLevel
    if [winfo exists .$this] { popup .$this ; return }
    set prnt $actParent($this)
    $this stash
    toplevel .$this -class Zorro
    set lb {}
    if {$actLabel($prnt) != {}} { set lb "$actLabel($prnt) " }
    wm title .$this "[$prnt label] $actTitle($this)"
    frame .$this.f1
    label .$this.f1.label -text "${lb}Title"
    entry .$this.title -relief sunken -textvariable actTitle($this)
    bind .$this.title <Return> "focus .$this.text"
    pack .$this.f1.label -side left
    pack .$this.title -side left -fill x -expand 1 -in .$this.f1
    if {$zorro(doneFlag)} {
	frame .$this.f1.pad
	pack .$this.f1.pad -padx 2
	checkbutton .$this.f1.done -text Done -variable actDone($this) \
	  -relief flat -command "$this doneFlag"
	pack .$this.f1.done -side right
    }
    pack .$this.f1 -padx 5 -pady 5 -fill x -expand 1
    if {$actLevel($this) < $zorro(maxlevel)} {
	frame .$this.f11
	label .$this.f11.label -text "Sub-task Descriptor"
	entry .$this.f11.title -relief sunken -textvariable actLabel($this)
	bind .$this.f11.title <Return> "focus $this.text"
	pack .$this.f11.label -side left
	pack .$this.f11.title -side left -fill x -expand 1
	pack .$this.f11 -padx 5 -pady 5 -fill x -expand 1
    }
    frame .$this.f2
    label .$this.f2.label -text {Notes}
    text .$this.text -relief sunken -yscrollcommand ".$this.scroll set" \
      -wrap word -borderwidth 2 -width 60 -height 10
    .$this.text insert end $actText($this)
    scrollbar .$this.scroll -command ".$this.text yview" -relief raised
    frame .$this.f2.tf
    pack .$this.text -fill both -expand 1 -side left -in .$this.f2.tf
    pack .$this.scroll -fill y -side right -in .$this.f2.tf
    pack .$this.f2.label -anchor w
    pack .$this.f2.tf -fill both -expand 1
    pack .$this.f2 -fill both -expand 1 -padx 5 -pady 5
    if $zorro(priorities) {
	$this priorityButtons .$this.pri Priority: actEnd
	checkbutton .$this.pri.var -text Variable -relief flat \
	  -variable tactPVar($this) -command "$this showStart"
	pack .$this.pri.var -side right
	pack .$this.pri -fill x -padx 5 -pady 5
	$this priorityButtons .$this.spri {Start Priority:} actStart
	frame .$this.spri.var -width [winfo reqwidth .$this.pri.var] \
	  -height [winfo reqheight .$this.pri.var]
	pack .$this.spri.var -side right
	if {$actStart($this) != {}} {
	    set tactPVar($this) 1
	    $this showStart
	}
    }
    frame .$this.due
    dateEntry .$this.due {Completion Date:} $actDue($this)
    menubutton .$this.due.catg -text Category: -menu .$this.due.catg.menu
    set m [menu .$this.due.catg.menu]
    if {$prnt != {root}} {
	foreach x [$actParent($prnt) actions] {
	    if [string match new* $x] continue
	    $m add command -label [$x title] \
	      -command "
	        $this configure -parent $x
	        .$this.due.catent configure -state normal
	        .$this.due.catent delete 0 end
	        .$this.due.catent insert end \[$x title\]
	        .$this.due.catent configure -state disabled
	      "
	}
    }
    entry .$this.due.catent -relief raised
    .$this.due.catent insert end [$prnt title]
    .$this.due.catent configure -state disabled
    pack .$this.due.catg -side left -padx 5
    pack .$this.due.catent -side left
    pack .$this.due -fill x -padx 5 -pady 5
    frame .$this.ctl
    button .$this.ctl.ok -text OK -command "if \[$this set\] {$this kill 0}" \
      -width 10
    button .$this.ctl.cancel -text Cancel -command "$this cancel" -width 10 
    pack .$this.ctl.ok .$this.ctl.cancel -side left -expand 1
    if [winfo exists [$this window]] {
	button .$this.ctl.del -text Delete -command "$this askDel" -width 10
	pack .$this.ctl.del -side left -expand 1
    }
    pack .$this.ctl -fill x -side bottom -padx 5 -pady 5
    focus .$this.title
    wm minsize .$this 1 1
    wm protocol .$this WM_DELETE_WINDOW "$this cancel"
}
#
proc action_cancel {this} {
    $this unstash
    $this kill 0
}
#
proc action_kill {this del} {
    global actParent actLevel
    set prnt $actParent($this)
    catch {destroy .$this}
    if {$del || ([Action :: selection $actLevel($prnt)] == $prnt &&
	![winfo exists [$this window]])} {
	$this delete
    }
    $prnt doneDisplay
}
#
proc configure {} {
    global zorro newZorro geomFlag sizeFlag geom
    if [winfo exists .@conf] {	wm deiconify .@conf ; raise .@conf ; return }
    if [winfo exists .@todo.ctl.conf] {
	.@todo.ctl.conf configure -state disabled
    }
    set geom [winfo geometry .@todo]
    foreach x [array names zorro] { set newZorro($x) $zorro($x) }
    set w [toplevel .@conf -class Zorro]
    wm title $w {Zorro Configuration}
    set geomFlag 0
    set sizeFlag 0
    pack [set x [frame $w.f0]] -fill x
    pack [set f [frame $x.f1]] -expand 1 -side left
    checkbutton $f.geom -text {Save Geometry} -relief flat \
      -variable geomFlag
    checkbutton $f.size -text {Save sizes} -relief flat \
      -variable sizeFlag
    pack $f.geom $f.size -anchor w
    checkbutton $f.done -text {Show done flag} -relief flat \
      -variable newZorro(doneFlag)
    checkbutton $f.show -text {Show done items} -relief flat \
      -variable newZorro(showDone)
    checkbutton $f.prior -text {Show priority} -relief flat \
      -variable newZorro(priorities)
    pack $f.done $f.show $f.prior -anchor w
    pack [set f [frame $x.f2]] -side left -expand 1
    label $f.sor -text {Sort Order}
    pack $f.sor -expand 1
    listbox $f.srt -width 12 -height [llength $newZorro(sortOrder)] \
      -relief raised -selectmode single
    bind $f.srt <B1-Motion> {
	set val [%W get [set v [%W curselection]]]
	set posn [%W nearest %y]
	%W delete $v
	%W insert $posn $val
	%W select set $posn
	break
    }
    bind $f.srt <2> break
    bind $f.srt <B2-Motion> break
    bind $f.srt <Shift-B1-Motion> break
    bind $f.srt <Shift-1> break
    foreach x $newZorro(sortOrder) { $f.srt insert end $x }
    pack $f.srt -expand 1
    pack [frame $w.l1 -background yellow -borderwidth 2] -fill x -pady 4
    pack [set f [frame $w.misc]] -fill x
    checkbutton $f.mbar -text {Menubar} -relief flat \
      -variable newZorro(menubar) -command "confMBar $w"
    checkbutton $f.noquit -text {No Quit Button} -relief flat \
      -variable newZorro(noQuit)
    pack $f.mbar $f.noquit -side left -expand 1
    pack [frame $w.l2 -background yellow -borderwidth 2] -fill x -pady 4
    pack [set fp [frame $w.new]] -fill x
    label $fp.label -text {New Style:}
    pack $fp.label -side left
    foreach x \
      {{Button button} {{Name Button} nameButton} {{List Item} listItem}} {
	set nm [lindex $x 1]
	set ln [lindex $x 0]
	radiobutton $fp.$nm -value $nm -variable newZorro(newStyle) \
	   -relief flat -text $ln
	pack $fp.$nm -side left
    }
    pack [frame $w.l3 -background yellow -borderwidth 2] -fill x -pady 4
    pack [set fp [frame $w.posn]] -fill x
    label $fp.label -text {Level Alignment:}
    pack $fp.label -side left
    foreach x {left right top bottom} {
	radiobutton $fp.$x -value $x -variable newZorro(placement) \
	   -relief flat -text $x
	pack $fp.$x -side left
    }
    pack [frame $w.l4 -background yellow -borderwidth 2] -fill x -pady 4
    pack [set f [frame $w.lcnt]] -fill x
    scale $f.lvl -label {Show levels} -from 1 -to 10 -showvalue 1 \
      -command "confLvl $w" -orient horizontal -variable newZorro(levels)
    scale $f.max -label {Max levels} -from 1 -to 10 -showvalue 1 \
      -command "confMax $w" -orient horizontal -variable newZorro(maxlevel)
    pack $f.lvl $f.max -fill x -side left -expand 1 -padx 5
    pack [frame $w.l5 -background yellow -borderwidth 2] -fill x -pady 4
    set f [frame $w.ctl]
    button $f.apply -text Apply -width 10 -command confApply
    button $f.save -text Save -width 10  -command confSave -state disabled
    button $f.dismiss -text Dismiss -command confDone -width 10
    pack $f.apply $f.save $f.dismiss -side left -expand 1 
    pack $f -fill x -padx 5 -pady 5
}
#
proc confLvl {win num} {
    global newZorro
    if {[set newZorro(levels) $num] > $newZorro(maxlevel)} {
	set newZorro(maxlevel) $num
	$win.lcnt.max set $num
    }
    $win.ctl.save configure -state normal
}
#
proc confMax {win num} {
    global newZorro
    if {[set newZorro(maxlevel) $num] < $newZorro(levels)} {
	set newZorro(levels) $num
	$win.lcnt.lvl set $num
    }
    $win.ctl.save configure -state normal
}
#
proc confMBar {win} {
    global newZorro
    set state [expr { $newZorro(menubar) ? {disabled} : {normal}}]
    foreach x {misc.noquit new.button new.listItem new.nameButton} {
	$win.$x configure -state $state
    }
}
#
proc confApply {} {
    global zorro newZorro sizeFlag selectAction geom
    set newZorro(sortOrder) {}
    set x 0
    while {$x < [.@conf.f0.f2.srt size]} {
	lappend newZorro(sortOrder) [.@conf.f0.f2.srt get $x]
	incr x
    }
    if $sizeFlag {
	set newZorro(listHeight) {}
	set newZorro(listWidth) {}
	set x 1
	while {$x <= $zorro(levels)} {
	    lappend newZorro(listHeight) [winfo height .@todo.f1.$x.list.l.frame]
	    lappend newZorro(listWidth) [winfo width .@todo.f1.$x.list.l.frame]
	    incr x
	}
    }
    foreach x [array names newZorro] { set zorro($x) $newZorro($x) }
    destroy .@todo
    control $geom
    if {[set x [llength $selectAction]] < $zorro(maxlevel)} {
	while {$x < $zorro(maxlevel)} {
	    lappend selectAction nil
	    incr x
	}
    }
}
#
proc confSave {} {
    global zorro defaults geomFlag geom
    confApply
    set f [glob ~]
    if [file exists $f/.zorrorc] { exec mv $f/.zorrorc $f/.zorrorc.bak }
    set desc [open ~/.zorrorc w]
    puts $desc "# zorro config file saved : [exec date]"
    foreach x [array names zorro] {
	if {[info exists defaults($x)] && $zorro($x) != $defaults($x)} {
	    puts $desc "set zorro($x) {$zorro($x)}"
	}
    }
    if $geomFlag { puts $desc "set zorro(geometry) {$geom}" }
    close $desc
    confDone
}
#
proc confDone {} {
    if [winfo exists .@todo.ctl.conf] {
	.@todo.ctl.conf configure -state normal
    }
    destroy .@conf
}
#
proc confirmQuit {} {
    if [ask {No Save Quit} {Really quit without saving your lists?}] { exit }
}
#
proc width {lvl} {
    global zorro
    if {[set wd [lindex $zorro(listWidth) $lvl]] == {}} {
	set wd [lindex $zorro(listWidth) \
	  [expr [llength $zorro(listWidth)] - 1]]
    }
    return $wd
}
#
proc height {lvl} {
    global zorro
    if {[set ht [lindex $zorro(listHeight) $lvl]] == {}} {
	set ht [lindex $zorro(listHeight) \
	  [expr [llength $zorro(listWidth)] - 1]]
    }
    return $ht
}
#
proc change {lvl x y} {
}
#
proc commitChange {lvl x y} {
}
#
set selAct {}
#
proc paste {lvl} {
    global selAct actParent cntActions
    if {$selAct != {}} {
	set prnt [Action :: selection [expr $lvl - 1]]
	set act [$selAct clone cut$cntActions {}]
	incr cntActions
	$prnt addAction $act
    }
}
#
proc copy {lvl del} {
    global cntActions actParent selAct
    if {[set act [Action :: selection $lvl]] == {nil}} return
    if {$selAct != {}} { $selAct delete }
    set selAct cut$cntActions
    incr cntActions
    $act clone $selAct {}
    set actparent($act) {}
    if $del { $act delete }
}
#
proc buildLevel {lvl w} {
    global zorro
    set f [frame $w.$lvl]
    bind $f <Enter> "focus $f.list.l.frame"
    set prv [expr $lvl - 1]
    if {$zorro(newStyle) == {nameButton}} {
	button $f.label -command "Action :: create $prv"
    } {
	label $f.label
    }
    set wd [width $lvl]
    set ht [height $lvl]
    set win [frame $f.list -relief groove -borderwidth 2]
    scrollbar $win.v -command "$win.l yview" -relief raised
    canvas $win.l -yscrollcommand "cscroll $win.v" -highlightthickness 0

    if !$zorro(shrink) { $win.l configure  -height $ht -width $wd }
    bind $win.l <Configure> "\[Action :: selection $prv\] resize %W %w %h"
    pack $win.l -side left -expand 1 -fill both
    set wf [frame $win.l.frame]
    if !$zorro(shrink) { $wf configure -width $wd }
    pack propagate $wf false
    bind $wf <Delete> "\[Action :: selection $lvl\] askDel"
    bind $wf <BackSpace> [bind $wf <Delete>]
    bind $wf <Control-h> [bind $wf <Delete>]
#    bind $wf <Control-x> "copy $lvl 1"
#    bind $wf <Control-v> "paste $lvl"
#    bind $wf <Control-c> "copy $lvl 0"
    bind $wf <Meta-n> "Action :: create $prv"
    bind $wf <Meta-d> "Action :: clone \[Action :: selection $lvl\]"
    $win.l create window 0 0 -window $wf -anchor nw
    pack $f.label -fill x -side top
    pack $f.list -fill both -expand 1 -after $f.label
    if {$zorro(newStyle) == {button}} {
	frame $f.ctl
	button $f.ctl.new -text New \
	  -command "Action :: create $prv"  -width 6
	pack $f.ctl.new -side left -expand 1 -padx 5 -pady 5
	pack $f.ctl -side bottom
    }
    pack $f -fill both -expand 1 -side $zorro(placement) -padx 5 -pady 5
    return $w.$lvl
}
#
proc save {} {
    set f [glob ~]/.zorrodb
    if [file exists $f] { exec mv $f $f.bak }
    set desc [open $f w]
    puts $desc {set zorro(creator) 1.1}
    set cnt 0
    foreach x [root actions] {
	$x saveAs $desc a$cnt root
	incr cnt
    }
    puts $desc "set cntActions $cnt"
    close $desc
}
#
proc quit {} {
    save
    exit 0
}
#
proc newMenu {m} {
    global zorro actParent
    $m delete 0 last
    set idx 1
    while {$idx < $zorro(maxlevel) && \
      [set v [Action :: selection $idx]] != {nil}} {
	$m add command -label "New [$v label]" \
	  -command "Action :: selection $actParent($v)"
	incr idx
    }
}
#
proc control {geom} {
    global zorro
    toplevel .@todo -class Zorro
    wm title .@todo Zorro
    frame .@todo.main
    if {$geom != {}} { wm geometry .@todo $geom}
    if $zorro(menubar) {
	set f [frame .@todo.mbar -relief raised -borderwidth 2]
	menubutton $f.file -text File -width 6 -anchor w -menu $f.file.menu
	set m [menu $f.file.menu]
	$m add cascade -label {New} -menu $m.new -command "newMenu $m.new"
	menu $m.new
	$m add command -label {Save} -command {save}
	$m add separator
	$m add command -label {Quit (no save)} -command exit
	$m add command -label Quit -command quit
	menubutton $f.edit -text Edit -width 6 -anchor w -menu $f.edit.menu
	set m [menu $f.edit.menu]
	$m add separator
	$m add command -label Configuration -command configure
	menubutton $f.help -text Help -width 6 -anchor w -menu $f.help.menu
	set m [menu $f.help.menu]
	$m add command -label Categories -command {help categories} \
	  -state disabled
	$m add command -label Actions -command {help actions} \
	  -state disabled
	$m add command -label Configuration -command {help config} \
	  -state disabled
	pack $f.file $f.edit $f.help -side left
	tk_menuBar $f $f.file $f.edit $f.help
	pack $f -fill x -in .@todo.main
	set zorro(newStyle) menu
    } \
    elseif {$zorro(newStyle) == {menu}} { set zorro(newStyle) listItem }
    set f [frame .@todo.f1]
    set x 1
    while {$x <= $zorro(levels)} { buildLevel $x $f ; incr x}
    root show $f $zorro(sortOrder)
    pack $f -fill both -expand 1 -in .@todo.main
    if !$zorro(menubar) {
	frame .@todo.ctl
	if !$zorro(noQuit) {
	    button .@todo.ctl.quit -text Quit -command quit -width 14
	    pack .@todo.ctl.quit -side left -expand 1
	    bind .@todo.ctl.quit <Shift-1> {tkButtonDown %W}
	    bind .@todo.ctl.quit <Shift-ButtonRelease-1> {
		set sc [%W cget -command]
		%W configure -command confirmQuit
		tkButtonUp %W
		%W configure -command $sc
	    }
	}
	button .@todo.ctl.save -text Save -command save -width 14
	button .@todo.ctl.help -text Help -command help -width 14
	button .@todo.ctl.conf -text Configure -command configure -width 14
	pack .@todo.ctl.save .@todo.ctl.help .@todo.ctl.conf \
	  -side left -expand 1
	pack .@todo.ctl -fill x -padx 5 -pady 5 -in .@todo.main
    }
    pack .@todo.main -fill both -expand 1
    wm protocol .@todo WM_DELETE_WINDOW quit
    wm resizable .@todo 1 1
}
#
proc init {} {
    global zorro defaults cntActions category selectAction \
      actTitle actDone actStart actEnd actDue actText actParent \
      actActions helpOn

    option add *foreground black widgetDefault
#    option add *background grey81 widgetDefault

    set zorro(defaultType) todo
    set zorro(creator) 1.1
    set zorro(patchlevel) 6
    set zorro(doneFlag) 1
    set zorro(priorities) 1
    set zorro(listHeight) {0 200 200}
    set zorro(listWidth) {0 150 300}
    set zorro(fastEdit) 0
    set zorro(priorityLabels) {1 2 3 4 5}
    set zorro(sortOrder) {done priority due begin title entered category}
    set zorro(showDone) 1
    set zorro(noQuit) 0
    set zorro(menubar) 0
    set zorro(placement) left
    set zorro(rootLabel) Category
    set zorro(subLabel) Task
    set zorro(copyTag) Copy
    set zorro(levels) 2
    set zorro(maxlevel) 2
    set zorro(shrink) 0
    set helpOn 0
#
# configure how new items are done : menu button listItem
#
    set zorro(newStyle) listItem
#
    if  {[info procs tk_*] != {}} {
	wm withdraw .
	bind Entry <Enter> { focus %W ; showHelp %W ; break}
	bind Entry <Leave> { focus . ; showHelp %W ; break}
	bind Text <Enter> { focus %W ; break}
	bind Text <Leave> { focus . ; break}
	label .foo
	set fg [.foo cget -foreground]
	destroy .foo
	set bg [. cget -background]
	set zorro(foreground) $fg
	set zorro(background) $bg
	if {[winfo screendepth .] != 1} {
	    set zorro(priorityBackground) "$bg $bg $bg $bg $bg"
	    set zorro(priorityForeground) "red magenta deeppink blue $fg"
	} {
	    set zorro(priorityBackground) "$bg $bg $bg $bg $bg"
	    set zorro(priorityForeground) "$fg $fg $fg $fg $fg"
	}
    }
    foreach x [array names zorro] { set defaults($x) $zorro($x) }
#
    set cntActions 0
    set category {}
    set selectAction {root}
    set i 0
    while {$i <= $zorro(maxlevel)} {
	lappend selectAction nil
	incr i
    }
    makeArray actTitle actDone actStart actEnd actDue actText actParent \
      actActions
}
#
proc today {} {
    global months
    set td [exec date]
    set yr [lindex $td 5]
    if {$yr == {DST}} { set yr [lindex $td 6] }
    return [format "%04d/%02d/%02d" $yr \
      [lsearch $months [lindex $td 1]] [lindex $td 2]]
}
#
set months {Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec}
set fullMonths {January February March April May June July August \
  September October November December}
set endDay {31 28 31 30 31 30 31 31 30 31 30 31}
#
set weekDay {Monday Tuesday Wednesday Thursday Friday Saturday Sunday}
#
proc dateEntry {win label day} {
    global dayVar mthVar yearVar mthIndex months
    set cr [$win cget -cursor]
    if {$day == {}} { set day [today]} 
    if [regexp {(.*)/0?(.*)/0?(.*)} $day m yearVar($win) mthIndex($win) \
      dayVar($win)] {
	set mthVar($win) [lindex $months $mthIndex($win)]
    }
    label $win.label -text $label
    pack $win.label -side left
    foreach x {day mth year} {
	frame $win.$x
	entry $win.$x.ent -width 4 -textvariable ${x}Var($win) \
	  -state disabled -relief raised -cursor $cr
	scrollbar $win.$x.scr -command "${x}Scroll $win" -relief raised \
	  -orient horizontal -width 12
	pack $win.$x.ent $win.$x.scr
	pack $win.$x -side left -padx 5
    }
}
#
proc leap {yr} {
    if {$yr % 4 == 0} {
	if {$yr % 400 == 0} { return 1 }
	return [expr !($yr % 100 == 0)]
    }
    return 0
}
#
proc lastDay {mth yr} {
    global endDay
    if {$mth == 1 && [leap $yr]} { return 29 }
    return [lindex $endDay $mth]
}
#
proc dayScroll {win num} {
    global dayVar endDay mthIndex yearVar
    set x $dayVar($win)
    incr x $num
    if {$x == 0} {
	mthScroll $win -1
	set x [lindex $endDay $mthIndex($win)]
    }\
    elseif {$x > [lastDay $mthIndex($win) $yearVar($win)]} {
	mthScroll $win 1
	set x 1
    }
    set dayVar($win) $x
}
#
proc mthScroll {win num} {
    global mthVar months endDay mthIndex dayVar yearVar
    if {[incr mthIndex($win) $num] < 0} {
	set mthIndex($win) 11
	yearScroll $win -1
    } \
    elseif {$mthIndex($win) == 12} {
	set mthIndex($win) 0
	yearScroll $win 1
    }\
    elseif {$dayVar($win) > [lastDay $mthIndex($win) $yearVar($win)]} {
	set dayVar($win) [lastDay $mthIndex($win) $yearVar($win)]
    }
    set mthVar($win) [lindex $months $mthIndex($win)]
}
#
proc yearScroll {win num} {
    global yearVar mthIndex dayVar
    incr yearVar($win) $num
    if {$mthIndex($win) == 1 && \
      $dayVar($win) > [lastDay $mthIndex($win) $yearVar($win)]} {
	set dayVar($win) [lastDay $mthIndex($win) $yearVar($win)]
    }
}
#
proc showHelp {win} {

}
#
proc help {args} {
    global helpOn
    set helpOn [expr !$helpOn]
    warn "Sorry, help is not implemented in this version. I am working on it."
}
#
proc pName {prio} {
    global zorro
    if {$prio == {}} { return { } }
    return [lindex $zorro(priorityLabels) [expr $prio - 1]]
}
#
proc pFground {prio} {
    global zorro
    if {$prio == {}} { return $zorro(foreground) }
    return [lindex $zorro(priorityForeground) [expr $prio - 1]]
}
#
proc pBground {prio} {
    global zorro
    if {$prio == {}} { return $zorro(background) }
    return [lindex $zorro(priorityBackground) [expr $prio - 1]]
}
#
proc pIndex {prio} {
    global zorro
    if {$prio == {}} { return -1 }
    return [lsearch $zorro(priorityLabels) $prio]
}
#
proc pValue {prio} {
    global zorro
    if {$prio == {}} { return {} }
    return [expr [lsearch $zorro(priorityLabels) $prio] + 1]
}
#
proc nil {args} { }
#
proc makeArray {args} {
    foreach x $args { global $x ; set ${x}(1) 1 ; unset ${x}(1) }
}
#
proc clean {txt} {
    regsub -all "\[\]\[\\\{\}\$\"\]" $txt {\\&} foo
    return $foo
}
#
proc ask {title msg} {
    return [expr {[tk_dialog .ask $title $msg question 0 OK Cancel] == 0}]
}
#
proc warn {msg} { tk_dialog .warn {Zorro Warning} $msg warning 0 OK }
#
proc doButtons {w param lv pars} {
    if {[llength $pars] > 0} {
	set arg [lindex $pars 0]
	frame $w.bot.0 -relief raised -border 1
	pack $w.bot.0 -side left -expand 1 -fill x -padx 5 -padx 5
	if {[set cmd [lindex $arg 1]] != {}} { append cmd " $param" }
	if {$lv != {}} {
	   bind $lv <Return> "$cmd ; destroy $w"
	   bind $lv <Tab> "focus $w.top.v0.value"
	}
	button $w.bot.0.button -text [lindex $arg 0] \
		-command "$cmd ; destroy $w"
	pack $w.bot.0.button -expand 1 -fill x -padx 5 -pady 5
	bind $w <Return> "$cmd ; destroy %W"
	set i 1
	foreach arg [lrange $pars 1 end] {
	    if ![string match {} [set cmd [lindex $arg 1]]] {
		append cmd " $param"
	    }
	    button $w.bot.$i -text [lindex $arg 0] \
	      -command "$cmd ; destroy $w"
	    pack $w.bot.$i -side left -expand 1 -fill x -padx 5 -pady 5
	    incr i
	}
    }
    bind $w <Any-Enter> {focus %W }
}
#
proc mkEntryBox {w title msgText entries args} {
    catch {destroy $w}
    toplevel $w -class Zorro
    wm title $w "$title"

    frame $w.top -relief raised
    frame $w.bot -relief raised
    pack $w.top -fill both -expand 1
    pack $w.bot -fill x
    message $w.top.message -text $msgText -aspect 800
    pack $w.top.message -expand 1 -fill both

    set param {}
    set vb 0
    set lv {}
    foreach entry $entries {
	frame $w.top.v${vb}
	set name $w.top.v${vb}.value
	label $w.top.v${vb}.label -text [lindex $entry 0]
	entry $name -relief sunken
	if {[set init [lindex $entry 1]] != {}} { $name insert end $init }
	append param " \[${name} get\]"
	pack $w.top.v${vb}.label -side left -padx 5 -pady 5
	pack $w.top.v${vb}.value -side left -expand 1 -fill x \
	  -padx 10 -pady 10
	pack $w.top.v${vb} -fill x -padx 5 -pady 5
	set lv $w.top.v${vb}.value
	incr vb
	bind $lv <Return> "notIdle {} ; focus $w.top.v${vb} "
	bind $lv <Tab> "notIdle {} ; focus $w.top.v${vb} "
    }
    doButtons $w $param $lv $args
    focus $w
}
#
init
foreach x [array names zorro] { set defaults($x) $zorro($x) }
#
set cntActions 0
#
Action root -label $zorro(rootLabel)
#
if [file exists ~/.zorrorc] { source ~/.zorrorc }
if {[lindex $zorro(sortOrder) 0] == 0} {
    set zorro(sortOrder) [lrange $zorro(sortOrder) 1 end]
}
if [file exists ~/.zorrodb] { source ~/.zorrodb }
if [info exists actCount] {
    set cntActions $actCount
    unset actCount
}
#
if {[info procs tk_*] != {}} {
    control [expr {[info exists zorro(geometry)] ? $zorro(geometry) : {}}]
} {
    foreach x [Action :: sort [array names actTitle] $zorro(sortOrder)] {
	[lindex $x 1] print
    }
}
