#
# Module for multiple widgets
#


# Switch-buffer command

proc th_all_widgets {class} {
  set all_widgets {}
  for {set w [th_next_widget . $class]} {$w != ""} \
	{set w [th_next_widget $w]} {
    lappend all_widgets $w
  }
  return $all_widgets    
}

# Goes to a new buffer
proc th_switch_buffer {w} {
  set all_titles {}
  set c [winfo class $w]
  foreach wid [th_all_widgets $c] {
    lappend all_titles [wm title [winfo toplevel $wid]]
  }

  set f [th_show_entry $w buffer]
  $f.l configure -text "Which:"
  global TH
  set TH(Completions,$f.e) [list [list th_line_complete [list th_list_completions $all_titles] none]]
  th_bind $f.e OK "th_hide_entry $w buffer ; th_switch_aux $c \"\[$f.e get\]\""
}

proc th_switch_aux {class title} {
  set all_titles {}
  set all_widgets [th_all_widgets $class]
  foreach w $all_widgets {
    lappend all_titles [wm title [winfo toplevel $w]]
  }
  if {[set i [lsearch $all_titles $title]] < 0} {bell ; return}
  th_focus [lindex $all_widgets $i]
}

# A quick bring-the-window-up-and-focus command.
proc th_focus {w} {
  set tl [winfo toplevel $w]
  wm deiconify $tl
  raise $tl
  update
  focus $w
}


# Moving below last (shown) window

proc th_move_below_last {w} {
  if {[set p [th_previous_widget $w]] == ""} {
    set p [th_previous_widget . [winfo class $w]]
  }
# Find a mapped widget before w
  while {($p != $w)} {
    if {[winfo ismapped $p] && [winfo ismapped [winfo toplevel $p]]} {break}
    if {[set p [th_previous_widget $p]] == ""} {
      set p [th_previous_widget . [winfo class $w]]
  }}
  if {$p == $w} {bell ; return}

  if {[winfo toplevel $w] == [winfo toplevel $p]} {
    if {[catch "pack $w -after $p"]} {bell}
  } else {
    scan [winfo geometry [winfo toplevel $p]] {%dx%d+%d+%d} \
  	his_width his_height his_x his_y
    wm geometry [winfo toplevel $w] "+$his_x\+[expr $his_y + $his_height]"
}}


# Focusing in all (shown) windows

# Sets up 'all' mode.
proc th_focus_all {w {i 0}} {
  if $i {set all "All"} else {set all "All Shown"}
  global TH
  set TH(All,Focus) ""
  set TH(All,Status) temporary
  set f [th_show_entry $w all]
  pack forget $f.l
  pack $f.e -expand no -fill none
  $f.e delete 0 end
  $f.e insert 0 $all
  $f.e configure -width 0

  th_bind $f.e All_Shown "th_toggle_all $w ; break"
  th_bind $f.e All_Windows "th_toggle_all $w ; break"
    bind kill_keys <Key> {if {[regexp . %A]} {set TH(Kill,Active) 0}}

  bind $f.e <Key> "if {[regexp . %A]} {
		th_allbinding $w $i %K %A} ; break"
  bind $f.e <Control-Key> "th_allbinding $w $i Control-Key-%K %A ; break"
  bind $f.e <Meta-Key>    "th_allbinding $w $i Meta-Key-%K %A ; break"
  bind $f.e <Control-Meta-Key>    "th_allbinding $w $i Control-Meta-Key-%K %A ; break"
  bind $f.e <Control-Tab> "continue"
  bind $f.e <Control-Shift-Tab> "continue"
}

# Switches from all-temporary to all-permenant, or exits all mode.
proc th_toggle_all {w} {
  global TH
  set f [th_frame $w].all
  if {($TH(All,Status) == "temporary")} {
    set TH(All,Status) "permanent"
    set all [$f.e get]
    $f.e delete 0 end
    $f.e insert 0 "$all Permanent"
    focus $f.e
  } else {th_hide_entry $w all
}}


# Performs function associated with keybinding in all windows, indluding this
# one (last).  c and events are as in th_return_binding. i if 1 sends to all
# windows, otherwise, just to mapped ones.
proc th_allbinding {w i b c} {
  if {![regexp . $c]} {return}
  if {$b == ""} {set b $c}
  set e "[th_frame $w].all.e"
  global TH
  if {($TH(All,Status) != "permanent")} {th_hide_entry $w all}

  set wc [th_all_widgets [winfo class $w]]
  foreach t $wc {
    if {($t == $w) || [string match "*.all.e" $t] ||
	((![winfo ismapped $t] || ![winfo ismapped [winfo toplevel $t]])
	&& !$i)} {continue}
    th_hide_entry $t all
    set f "$t$TH(All,Focus)" ; focus $f
    if {[set cmd [th_return_binding $f $b $c]] != ""} {
      catch $cmd
  }}
  set f "$w$TH(All,Focus)"
# Dont execute the keybinding on the all entry, that would make an infinite loop
  if {$TH(All,Focus) == "_fm.all.e"} {set f $w}
  focus $f
  if {[set cmd [th_return_binding $f $b $c]] != ""} {catch $cmd}

  if {[catch "winfo ismapped $w" result]} {return}
# Window must have been destroyed.
  if {!$result} {th_hide_entry $w all ; return}
# Window still exists, but was unmapped.

# Save focus here, in case it changed.
  set TH(All,Focus) [string range [focus -lastfor $w] [string length $w] end]
  if {($TH(All,Status) == "permanent")} {  focus $e}
}

