#
# These routines complete a line of text.
#


# Like th_substring_complete, but works on the whole line of text.
proc th_line_complete {function dummy s} {
  return [th_substring_complete $function none $s]
}

### SubString replacement.

# Unless stated otherwise, the following string functions should return the
# following format: {result message}. If result is empty, the command failed.

# Replaces s with its Tcl result (in global mode) (s = tcl-command])
proc th_string_tcl_result {s} {
  if {![string match *\] $s]} {return [list "" ""]}
# If the user entered an erroneous Tcl command (i.e. it was *meant* to be
# Tcl (the braces indicate such), let the Tk error handle the problem.
  global TH
  if {[catch "$TH(Completion,Prefix) [string trimright $s \]]" result]} {
    return [list "" "Tcl Command failed because:\n$result"]
  } else {return [list $result ""]
}}

# Replaces s with its Tcl value (s == "varname" or "arrayname(index)")
proc th_string_global_value {s} {
  if {$s == ""} {return [list "" ""]}
  global TH
  if {![catch "$TH(Completion,Prefix) [list set $s]" result]} {return [list $result ""]}
  if {[eval $TH(Completion,Prefix) array exists $s]} {return [list "\$$s\(" ""]
  } else {return [list "" ""]
}}

# Replaces s with its Tcl glob equivalent.
proc th_string_glob_files {s} {
  if {$s == ""} {return [list "" ""]}
  global TH
  if {[catch "$TH(Completion,Prefix) glob -nocomplain -- [list $s]" result]} {
    return [list "" ""]}
  if {($result == $s) || ($result == "")} {return [list "" ""]
  } else {return [list " $result" ""]
}}


### SubString completion

# Completes a filename
proc th_filter_glob {prefix args} {
  global TH
  if {[catch "$TH(Completion,Prefix) glob -nocomplain -- [list [list $prefix*]]" result]} {set result ""}
  if {([llength $result] == 1) && [file isdirectory [lindex $result 0]]} {
    set result [list "[lindex $result 0]/"]}
  return "Possible files:\n$result"
}

# Completes a Tcl command name.
proc th_filter_cmds {prefix args} {
  global TH
  return "Possible Tcl commands:\n[eval $TH(Completion,Prefix) \
    info commands [list [list $prefix*]]]"
}

# Completes either variable or array index.
proc th_filter_vars {prefix args} {
  set list [th_string_divide $prefix \(]
  global TH
  if {[lindex $list 1] == ""} {
    return "Possible variables:\n[eval $TH(Completion,Prefix) info globals [list $prefix*]]"}
# Must complete array index
  set array [lindex $list 0] ;   set index [lindex $list 2]
  if {[catch "$TH(Completion,Prefix) array names $array" names]} {return ""
  } else {set message [th_filter_completions $index $names]
    set indices [th_remove_prefix $message]
    set results ""
    foreach index $indices {
      set results [lappend results "$array\($index\)"]}
    return "Possible array indices:\n$results"
}}

# Returns all the menuentries in all menus descended from m.
proc th_return_menu_entries {m {recursive 0}} {
  global TH
  set result ""
  set last [eval $TH(Completion,Prefix) $m index last]
  for {set i 0} {$i <= $last} {incr i} { 
    if {[catch "$TH(Completion,Prefix) $m entrycget $i -label" list]} {
      continue}
    lappend result $list
    if $recursive {
      if {![catch "$TH(Completion,Prefix) $m entrycget $i -menu" list]} {
        eval lappend result [th_return_menu_entries $list 1]
  }}}
  return $result
}

# Completes a menu entry.
proc th_menu_entries {m prefix args} {
  return "Possible Menu Entries:\n[th_remove_prefix [th_filter_completions \
		$prefix [th_return_menu_entries $m]]]"
}

# Like th_menu_entries, but includes submenus as well.
proc th_cascading_menu_entries {m prefix args} {
  global TH
  set menu [eval $TH(Completion,Prefix) $m cget -menu]
  return "Possible Menu Entries:\n[th_remove_prefix [th_filter_completions \
		$prefix [th_return_menu_entries $menu 1]]]"
}

# Returns the appropriate entries off a listbox.
proc th_listbox_entries {l prefix args} {
  global TH
  set result ""
  set end [eval $TH(Completion,Prefix) $l size]
  for {set i 0} {$i < $end} {incr i} { 
    lappend result [eval $TH(Completion,Prefix) $l get $i]
  }
  return "Possible Listbox Entries:\n[th_remove_prefix [th_filter_completions \
		$prefix $result]]"
}

# Completions are taken off the text items in canvas c
proc th_canvas_text_entries {c prefix args} {
  global TH
  set result ""
  foreach item [eval $TH(Completion,Prefix) $c find withtag all] {
    if {[catch "$TH(Completion,Prefix) $c itemcget $item -text" text]} {
	continue}
    lappend result $text
  }
  return "Possible Canvas Entries:\n[th_remove_prefix [th_filter_completions \
		$prefix $result]]"
}

# Takes completions off l, an arbitrary list of completions.
proc th_list_completions {l prefix args} {
  return [th_filter_completions $prefix $l]
}
