+ set ew $cw.$ix
+
+ debug "MAKE-CONTROL-GRID-ELEM $cw $kind $ix $ekind $rows $inrow $ew"
+
+ eval [list $ekind $ew] $args
+
+ switch -exact $kind {
+ ix {
+ grid configure $ew -sticky sw \
+ -row [expr {$ix / $inrow}] \
+ -column [expr {$ix % $inrow}]
+ }
+ final {
+ grid configure $ew -sticky se \
+ -row [expr {$rows-1}] \
+ -column [expr {$inrow-1}]
+ }
+ default {
+ error "$kind ?"
+ }
+ }
+ return $ew
+}
+
+proc control-tickbox-flip {varsvn values onflip} {
+ upvar #0 $varsvn vars
+ foreach val $values {
+ set vars($val) [expr {!$vars($val)}]
+ }
+ $onflip c.-tickbox-flip $varsvn $values
+}
+
+proc populate-control-grid-tickboxes {cw rows inrow varsvn values flipvalues
+ label_kind valvn default_get label_get onflip} {
+ debug "POPULATE-CONTROL-GRID-TICKBOXES $cw $rows $inrow $varsvn\
+ [list $values] $label_kind $valvn"
+
+ upvar #0 $varsvn vars
+ upvar 1 $valvn val
+ set count [llength $values]
+
+ begin-control-grid $cw $count $rows $inrow
+
+ for {set ix 0} {$ix < $count} {incr ix} {
+ set val [lindex $values $ix]
+ set vars($val) [uplevel 1 $default_get]
+ set ew [make-control-grid-elem $cw ix $ix checkbutton \
+ -variable ${varsvn}($val) \
+ -font fixed \
+ -command [list $onflip c.-g.-tickbox $cw $val]]
+ $ew configure -$label_kind [uplevel 1 $label_get]
+ switch -exact $label_kind {
+ image { $ew configure -height 16 }
+ }
+ }
+ [make-control-grid-elem $cw final invert button] \
+ configure \
+ -text flip -padx 0 -pady 0 \
+ -command [list control-tickbox-flip $varsvn $flipvalues $onflip]
+}
+
+#---------- smashing ----------
+
+proc smash-code {code} {
+ manyset [split $code _] inport size subclass lockown xabbrev
+
+ upvar #0 smash_sizemap($size) smsize
+
+ global smash_subclass
+ if {$smash_subclass > 1} {
+ set subclass {}
+ } elseif {$smash_subclass && [string length $subclass]} {
+ set subclass !
+ }
+
+ global smash_owner
+ switch $smash_owner {
+ 0 { }
+ 1 { regsub {[12]$} $lockown 5 lockown }
+ 2 {
+ if {[regexp {^0.} $lockown]} {
+ # battle ready / all lock states
+ set lockown 03
+ } elseif {[regexp {^.0} $lockown]} {
+ # not battle ready / yours
+ set lockown 40
+ } else {
+ # state (not battle ready) / not known to be yours
+ regsub {.$} $lockown 4 lockown
+ }
+ }
+ 3 { regsub {.$} $lockown {3} lockown }
+ 4 { set lockown 33 }
+ }
+
+ global smash_xabbrev_map
+ set xabbrev [string map $smash_xabbrev_map $xabbrev]
+
+ return [join [list $inport $smsize $subclass $lockown $xabbrev] _]
+}
+
+proc smash-prepare {} {
+ global vc_codes smash_sizemap smash_size smash_sizeinexact
+ set mapto {}
+ catch { unset smash_sizeplus }
+ foreach size $vc_codes {
+ if {!$smash_size($size)} {
+ set mapto $size
+ } else {
+ set smash_sizeinexact($mapto) 1
+ }
+ set smash_sizemap($size) $mapto
+ }
+
+ global smash_xabbrev_a smash_xabbrev_b smash_xabbrev_map
+ set smash_xabbrev_map {}
+ foreach a [split $smash_xabbrev_a ""] b [split $smash_xabbrev_b ""] {
+ if {![string length $a]} continue
+ lappend smash_xabbrev_map $a $b
+ }
+ debug "SMASH-PREPAE xabbrev_map=[list $smash_xabbrev_map]"
+}
+
+proc make-smasher {sma label ekind} {
+ return [make-control .smash $sma $label $ekind]
+}
+
+proc make-radio-smasher {sma label variable descs rows inrow} {
+ set w [make-smasher $sma $label frame]
+ begin-control-grid $w [llength $descs] $rows $inrow
+ for {set i 0} {$i < [llength $descs]} {incr i} {
+ make-control-grid-elem $w ix $i \
+ radiobutton \
+ -variable $variable -value $i \
+ -command [list redraw-needed radio-smasher $sma] \
+ -text [lindex $descs $i]
+ }
+ return $w
+}
+
+proc make-smashers {} {
+ global vc_codes vc_code2abbrev
+ set cw [make-smasher size "Size\n round\n down" frame]
+ populate-control-grid-tickboxes $cw 2 0 smash_size \
+ $vc_codes [lrange $vc_codes 1 end] \
+ image val { expr 0 } { expr {"icon/$vc_code2abbrev($val)"} } \
+ redraw-needed
+ $cw.0 configure -state disabled
+
+ glset smash_subclass 0
+ make-radio-smasher subclass Class smash_subclass \
+ {Show Normal/LE Hide} 1 0
+
+ glset smash_owner [expr {[have-ownership] ? 0 : 3}]
+ set cw [make-radio-smasher owner "Lock/\nowner" smash_owner \
+ {Show Yours? {For you} Lock Hide} 2 3]
+ if {![have-notes]} { $cw.0 configure -state disabled }
+ if {![have-ownership]} {
+ foreach ix {1 2} { $cw.$ix configure -state disabled }
+ }
+
+ set cw [make-smasher xabbrev "Flags" frame]
+ foreach ix {1 3} ab {a b} width {14 12} {
+ set vn smash_xabbrev_$ab
+ global $vn
+ set $vn {}
+ entry $cw.$ix -textvariable $vn -width $width
+ trace add variable $vn write [list redraw-needed $vn]
+ }
+ set ix 0
+ foreach str {y/ / /d} { label $cw.$ix -text $str; incr ix 2 }
+ eval pack [lsort [winfo children $cw]] -side left
+}
+
+#---------- filtering ----------
+
+set filters {}
+
+proc filter-values/size {} { global vc_codes; return $vc_codes }
+proc filter-icon/size {code} {
+ upvar #0 vc_code2abbrev($code) abb
+ return icon/$abb
+}
+proc filter-default/size {code} { return 1 }
+proc filter-says-yes/size {codel} {
+ set sizecode [lindex $codel 1]
+ upvar #0 filter_size($sizecode) yes
+ return $yes
+}
+
+proc filter-values/lock {} { return {0 1 2} }
+proc filter-icon/lock {lock} { return [code-lockown2icon ${lock}3] }
+proc filter-default/lock {lock} { return 1 }
+proc filter-says-yes/lock {codel} {
+ regexp {^.} [lindex $codel 3] lock
+ upvar #0 filter_lock($lock) yes
+ debug "FILTER-SAYS-YES/LOCK $codel $lock $yes"
+ return $yes
+}
+
+proc filter-values/own {} { return {0 1 2} }
+proc filter-icon/own {own} { return [code-lockown2icon 3${own}] }
+proc filter-default/own {own} { return 1 }
+proc filter-says-yes/own {codel} {
+ regexp {.$} [lindex $codel 3] own
+ upvar #0 filter_own($own) yes
+ debug "FILTER-SAYS-YES/OWN $codel $own $yes"
+ return $yes
+}
+
+proc filter-values/lockown {} {
+ foreach lv {0 1 2} {
+ foreach ov {0 1 2} {
+ lappend vals "$lv$ov"
+ }
+ }
+ return $vals
+}
+proc filter-icon/lockown {lockown} { return [code-lockown2icon $lockown] }
+proc filter-default/lockown {lockown} {
+ return [regexp {^[01]|^2[^1]} $lockown]
+}
+proc filter-says-yes/lockown {codel} {
+ set lockown [lindex $codel 3]
+ upvar #0 filter_lockown($lockown) yes
+ debug "FILTER-SAYS-YES/LOCKOWN $codel $lockown $yes"
+ return $yes
+}
+
+proc filter-validate/xabbre {re} {
+ if {[catch {
+ regexp -- $re {}
+ } emsg]} {
+ regsub {^.*:\s*} $emsg {} emsg
+ regsub {^.*(.{30})$} $emsg {\1} emsg
+ return $emsg
+ }
+ return {}
+}
+proc filter-says-yes/xabbre {codel} {
+ global filter_xabbre
+ set xabbrev [lindex $codel 4]
+ return [regexp -- $filter_xabbre $xabbrev]
+}
+
+proc make-tickbox-filter {fil label rows inrow} {
+ set values [filter-values/$fil]
+
+ if {![catch { info args filter-icon/$fil }]} {
+ set label_get { filter-icon/$fil $val }
+ set label_kind image
+ } else {
+ set label_get { filter-map/$fil $val }
+ set label_kind text
+ }
+
+ set fw [make-filter $fil $label frame]
+
+ populate-control-grid-tickboxes $fw $rows $inrow filter_$fil \
+ $values $values \
+ $label_kind val { filter-default/$fil $val } $label_get \
+ specific-filter-adjusted
+}
+
+proc entry-filter-changed {fw fil n1 n2 op} {
+ global errorInfo
+ upvar #0 filter_$fil realvar
+ upvar #0 filterentered_$fil entryvar
+ global def_background
+ debug "entry-filter-changed $fw $fil $entryvar"
+ if {[catch {
+ set error [filter-validate/$fil $entryvar]
+ if {[string length $error]} {
+ $fw.error configure -text $error -foreground white -background red
+ } else {
+ $fw.error configure -text { } -background $def_background
+ set realvar $entryvar
+ specific-filter-adjusted entry-filter-changed $fw
+ }
+ } emsg]} {
+ puts stderr "FILTER CHECK ERROR $emsg $errorInfo"
+ }
+}
+
+proc make-entry-filter {fil label def} {
+ global filterentered_$fil
+ upvar #0 filter_$fil realvar
+ set realvar $def
+ set fw [make-filter $fil $label frame]
+ entry $fw.entry -textvariable filterentered_$fil
+ label $fw.error
+ glset def_background [$fw.error cget -background]
+ trace add variable filterentered_$fil write \
+ [list entry-filter-changed $fw $fil]
+ pack $fw.entry $fw.error -side top -anchor w
+}
+
+proc make-filter {fil label ekind} {
+ global filters
+ lappend filters $fil
+ return [make-control .filter $fil $label $ekind]
+}
+
+proc make-filters {} {
+ global filter_lockown_separate
+ make-tickbox-filter size Size 2 0
+ if {!$filter_lockown_separate} {
+ make-tickbox-filter lockown "Lock/\nowner" 2 6
+ } else {
+ make-tickbox-filter lock "Lock" 1 0
+ if {[have-notes]} {
+ make-tickbox-filter own "Owner" 1 0
+ }
+ }
+ make-entry-filter xabbre "Flags\n regexp" {}
+}
+
+proc specific-filter-adjusted {args} {
+ glset filterstyle 3
+ eval redraw-needed $args
+}
+
+proc filterstyle-changed {n1 n2 op} {
+ global filterstyle
+ debug "FILTERSTYLE-CHANGED $filterstyle"
+ redraw-needed filterstyle-changed
+}
+
+proc filters-say-yes {code} {
+ global filters filterstyle
+ set codel [split $code _]
+ set lockown [lindex $codel 3]
+ switch -exact $filterstyle {
+ 0 { return 1 }
+ 1 { return [filter-default/lockown $lockown] }
+ 2 { return [regexp {^.0} $lockown] }
+ 3 { }
+ default { error $filterstyle }
+ }
+
+ foreach fil $filters {
+ if {![filter-says-yes/$fil $codel]} {
+ debug "FILTERS-SAY-YES $code NO $fil"
+ return 0
+ }
+ }
+ debug "FILTERS-SAY-YES $code YES $filters"
+ return 1
+}
+