#
# Module for performing searches in Canvas widgets
#


# Searches for next occurrence of string in w.
proc th_Canvas_find {w string {next 1} {direction "forward"} {type "string"}} {
  global TH
  if {$TH(Search,Select,[winfo class $w]) == "sel"} {
    set was_search [$w select item]
    $w select clear
  } else {set was_search [$w focus]}

  if {$was_search == ""} {
    set border(forward) [lindex [$w find withtag all] 0]
    set border(backward) end
  } else {
    if $next {
      set border(forward) [expr $was_search +1]
      set border(backward) [expr $was_search -1]
    } else {
      set border(forward) $was_search
      set border(backward) $was_search
  }}

  if {[catch "set TH(Search,Failed,$w)"]} {set TH(Search,Failed,$w) 0}
  if $TH(Search,Failed,$w) {
    set border(forward) 0
    set border(backward) end
  }

  set length [string length $string]
  if {($length == 0)} {return 0}

  set found [th_Canvas_[set type]_[set direction] $w $border($direction) $string]
  if {($found != -1)} {
    if {$TH(Search,Select,[winfo class $w]) == "sel"} {
      $w select from $found 0
      $w select to $found end
    }
    set focus [focus -displayof [winfo toplevel $w]]
    $w focus $found
    th_Canvas_goto $w 0 0
    focus $focus
    set TH(Search,Failed,$w) 0
    return 1
  } else {
    set TH(Search,Failed,$w) 1
    return 0
}}


# Finds first occurrence of string after point in widget w
# Returns index of found occurrence, or -1 if unsuccessful.
# Here point is an item number, or end.
proc th_Canvas_string_forward {w point string} {
  global TH
  if {$point == "end"} {return -1}

  foreach item [$w find withtag all] {
    if {$item < $point} {continue}
    if {[catch {$w itemconfigure $item -text} result]} {continue}
    set text [lindex $result 4]
    if $TH(Search,Case,$w) {set text [string tolower $text]}
    if {([string first $string $text] != -1)} {return $item}
  }
  return -1
}

# Finds last occurrence of string before point in widget w
# Returns start and end of occurance or "" if unsuccessful.
proc th_Canvas_string_backward {w point string} {
  global TH
  set list [$w find withtag all]
  set l [expr [llength $list]]
  if {$point == "end"} {set point $l}

  for {set x [expr $l - 1]} {$x >= 0} {incr x -1} {
    if {[lindex $list $x] > $point} {continue}
    if {[catch {$w itemconfigure [lindex $list $x] -text} result]} {continue}
    set text [lindex $result 4]
    if $TH(Search,Case,$w) {set text [string tolower $text]}
    if {([string first $string $text] != -1)} {return [lindex $list $x]}
  }
  return -1
}


# Finds first occurrence of string after point in widget w using regexp.
# Returns start and end of occurance or "" if unsuccessful.
proc th_Canvas_regexp_forward {w point string} {
  global TH
  if {$point == "end"} {return -1}

  foreach item [$w find withtag all] {
    if {$item < $point} {continue}
    if {[catch {$w itemconfigure $item -text} result]} {continue}
    if $TH(Search,Case,$w) {
      if {[catch {regexp -nocase -- $string [lindex $result 4]} r]} {bell ; return -1}
    } else {if {[catch {regexp -- $string [lindex $result 4]} r]} {bell ; return -1}}
    if $r {return $item}
  }
  return -1
}

# Like regexp_forward, but searches from beginning to point.
proc th_Canvas_regexp_backward {w point string} {
  global TH
  set list [$w find withtag all]
  set l [expr [llength $list]]
  if {$point == "end"} {set point $l}

  for {set x [expr $l - 1]} {$x >= 0} {incr x -1} {
    if {[lindex $list $x] > $point} {continue}
    if {[catch {$w itemconfigure [lindex $list $x] -text} result]} {continue}
    if $TH(Search,Case,$w) {
      if {[catch {regexp -nocase -- $string [lindex $result 4]} r]} {bell ; return -1}
    } else {if {[catch {regexp -- $string [lindex $result 4]} r]} {bell ; return -1}}
    if $r {return [lindex $list $x]}
  }
  return -1
}
