#
# Operations for paragraph manipulation in Text widgets.
#

# The following functions work on paragraphs (ranges of text separated by blank
# lines). They return an index or "" if unsuccessful.

proc th_para_begin {w index} {
  if {[set i [$w search -backward -regexp {$^} $index 1.0]] == ""} {
    return 1.0} else {return "$i+1c"}
}

proc th_para_end {w index} {
  if {[set i [$w search -forward -regexp {$^} "$index-1c" end]] == ""} {
    return end} else {return $i}
}

proc th_para_next {w index} {
  if {[set in [th_para_end $w $index]] == "end"} {return ""}
  scan [$w index $in] "%d.%d" i dummy
  scan [$w index end] "%d.%d" e dummy
  for {} {$i < $e} {incr i} {
    if {([$w get "$i.0"] != "\n")} {return "$i.0"}}
  return ""
}

proc th_para_prev {w index} {
  if {[$w compare [set begin [th_para_begin $w $index]] != $index]} {
    return $begin }
  scan [$w index $begin] "%d.%d" i dummy
  for {incr i -1} {$i > 1} {incr i -1} {
    if {([$w get "$i.0"] != "\n")} {return [th_para_begin $w "$i.0"]}}
  return ""
}

# Allows one to do an undoable change (specified by $fn) to the current
# paragraph
proc th_Text_para_change {w fn} {
  if {[catch {$w index sel.first}]} {
    set selected 0
    set start [$w index [th_para_begin $w insert]]
    if {[$w compare [set end [th_para_end $w $start]] < insert]} {bell ; return}
  } else {
    set start sel.first ; set end sel.last
    set selected 1
  }
  $fn $w $start $end
  if $selected {set end sel.last} else {set end [th_para_end $w $start]}
  th_Text_tag_regions $w paragraph th_para_begin th_para_end th_para_next $start $end
}

# Adds an indentation to the current paragraph (Used by th_Text_para_change)
# If delete is nonzero, deletes an indentation instead.
proc th_Text_para_indent {w {delete 0}} {
  set prefix ["[th_frame $w].indent.e" get]
  th_hide_entry $w indent

  if {([catch {$w index sel.first}])} {bell ; return}
  if {($prefix == "")} {bell ; return}
  set mark1 [$w index "sel.first linestart"]
  $w mark set mark2 "sel.last -1c lineend"
  set chars [$w get $mark1 mark2]

  if $delete {
    th_Text_delete_prefix $w $mark1 mark2 $prefix
    th_Text_format $w $mark1 mark2 [expr [$w cget -width] - [string length $prefix]] 0
    set desc "Un-Indent"
  } else {
    th_Text_format $w $mark1 mark2 [expr [$w cget -width] - [string length $prefix]] 0
    th_Text_add_prefix $w $mark1 mark2 $prefix
    set desc "Indent"
  }
  set mark2 [$w index mark2] ; $w mark unset mark2
  $w tag remove sel 1.0 end
  $w tag add sel $mark1 $mark2
  th_Text_undoable_replace $w $mark1 $mark2 $chars $desc
}
