#
# Module for balancing parens in Entry widgets
#


# Returns the index (in the TH(Paren...) series) of the last right pair
# before insert.
proc th_string_prev_exp {s w index {i 0}} {
  global TH
  for {set l [llength $TH(Paren,Right,$w)]} {$i < $l} {incr i} {
    set right [lindex $TH(Paren,Right,$w) $i]
    if {$right == [string range $s [expr $index - [string length $right]] [expr $index - 1]]} {
      return $i
  }}
  return -1
}

# The version for entries
proc th_Entry_prev_exp {w {i 0}} {return [th_string_prev_exp [$w get] $w [$w index insert] $i]}

# Returns the index (in the TH(Paren...) series) of the next left pair
# after insert
proc th_string_next_exp {s w index {i 0}} {
  global TH
  for {set l [llength $TH(Paren,Left,$w)]} {$i < $l} {incr i} {
    set left [lindex $TH(Paren,Left,$w) $i]
    if {$left == [string range $s $index [expr $index - 1 + [string length $left]]]} {
      return $i
  }}
  return -1
}

# Ditto for entries
proc th_Entry_next_exp {w {i 0}} {return [th_string_next_exp [$w get] $w [$w index insert] $i]}


# Returns index of closesst previous lone left partner, or "" if unsuccessful.
proc th_string_left_exp {s index left right nest} {
  set close_trace [expr $index - [string length $right]]
  set open_trace $close_trace
  while (1) {
    if {[set open_trace [string last $left [string range $s \
	0 [expr $open_trace - 1]]]] == -1} {return ""}
    if {(!$nest) || [set close_trace [string last $right [string range $s \
	$open_trace [expr $close_trace - 1]]]] == -1} {return $open_trace }
    incr close_trace $open_trace
}}

proc th_Entry_left_exp {w index left right nest} {return [th_string_left_exp [$w get] [$w index $index] $left $right $nest]}

# Like th_string_left_exp, but goes from the, umm, right!
proc th_string_right_exp {s index left right nest} {
  set close_trace [expr $index + [string length $left] - 1]
  set open_trace $close_trace
  while {1} {
    if {[set tmp [string first $right [string range $s \
	[expr $close_trace +1] end]]] == -1} {return ""}
    incr close_trace $tmp ; incr close_trace
    if {(!$nest) || [set tmp [string first $left [string range $s \
        [expr $open_trace +1] $close_trace]]] == -1} {
      return [expr $close_trace + [string length $right]]}
    incr open_trace $tmp ; incr open_trace
}}

proc th_Entry_right_exp {w index left right nest} {return [th_string_right_exp [$w get] [$w index $index] $left $right $nest]}


# Returns a message for match being found (of exp_type). Match may be empty;
# in which case nothing is returned.
proc th_Entry_report_exp {w start end left right nest} {
  global TH
  if {$TH(Paren,Select,Entry) == "sel"} {$w select clear}
  if {($start == "")} {return ""}
  set start_end [expr $start + [string length $left] -1]
  if {$TH(Paren,Select,Entry) == "sel"} {
    $w select from $start
    $w select to [expr $start_end +1]
  }
  return [string range [$w get] 0 $start_end]
}

# Counts instances of $c between $start and $end in $s
proc th_string_char_count {s c start end} {
  set offset 0 ; set count 0
  while {([set trace [string first $c [string range $s $start $end]]] \
	!= -1)} {
    incr start $trace
    incr start
    incr count
  }
  return $count
}

proc th_Entry_char_count {w c start end} {return [th_string_char_count [$w get] $c [$w index $start] [$w index $end]]}
