#
# Module for managing grids in Text widgets
#

# Called by a text widget to tell t what to yview
proc th_Text_xview {w t x1 x2} {
  $t xview moveto $x1
}

# Turns on or off the horizontal grid on w. Side indicates where to put it.
proc th_Text_toggle_grid_x {w {side bottom}} {
  if {[winfo manager $w] != "pack"} {
    set tl "[set w].gridx"
    set g "[set tl].g"
  } else {
    set tl ""
    set g "[set w]_gridx"}

  global TH
  if {[winfo exists $g]} {
# turn grid off
    if {[scan [$g cget -xscrollcommand] "%s set" sc] >= 0} {
      $w configure -xscrollcommand "$sc set"
    } else {$w configure -xscrollcommand {}}

    set TH(Grid_X,$w) 0
    if {$tl != ""} {destroy $tl} else {destroy $g}
  } else {
    set TH(Grid_X,$w) 1
# turn grid on
    if {$tl != ""} {
      toplevel $tl
      wm protocol $tl WM_DELETE_WINDOW { }
      wm transient $tl [winfo toplevel $w]
    }
    entry $g -relief ridge -font [$w cget -font] \
	-width [$w cget -width] -borderwidth 2
    if {$tl != ""} {pack $g -expand yes -fill x
    } else {
      set w_side [lindex [pack info $w] end]
      eval pack $g -anchor n [lrange [pack info $w] 6 15] -expand 0 -side $side -before $w
      switch [list $w_side $side] {
        {top bottom} - {left right} - {bottom top} - {right left} {
          pack $g -after $w -side $w_side
      }}

      set fill [lindex [pack info $w] 7]
      if {$fill == "both"} {pack $g -fill x
      } elseif {$fill == "y"} {pack $g -fill none}}

# Disable scanning on g.
    bindtags $g "$g ."

# Fill g with column numbers, must figure out how many to fill first.
    set use_screenwidth 1
    set width [$w cget -width]
    if {[$w cget -wrap] == "none"} {
      for {set c 1.0} {[$w compare $c < end]} {set c [$w index "$c +1 line"]} {
        set l [string length [$w get $c "$c lineend"]]
        if {$l > $width} {set width $l ; set use_screenwidth 0}
    }}
    incr width

    $g delete 0 end
    if $use_screenwidth {
      update ; set width [winfo reqwidth $g]
      for {set column 0} {[$g index @$width] == $column} {incr column} {
        if {[expr $column % 10] == 0} {
          $g insert end $column
          incr column [expr [string length $column] - 1]
        } elseif {[expr $column % 5] == 0} {$g insert end "+"
        } else {$g insert end "-"}
    }} else {
      for {set column 0} {$column <= $width} {incr column} {
        if {[expr $column % 10] == 0} {
          $g insert end $column
          incr column [expr [string length $column] - 1]
        } elseif {[expr $column % 5] == 0} {$g insert end "+"
        } else {$g insert end "-"}
    }}
    $g configure -state disabled

# Tie w's xscrollcommand over to g.
    $w xview moveto 0 ; $g xview moveto 0
# Texts can't reliably tell you how far along the x line they're scrolled.
    if {[scan [$w cget -xscrollcommand] "%s set" sc] >= 0} {
# Give g the responsibility of moving w's scrollbar.
      $g configure -xscrollcommand "$sc set"
    }
    $w configure -xscrollcommand "th_Text_xview $w $g"
}}


# Called by a text widget to tell t what to yview
proc th_Text_yview {w t y1 y2} {
  scan [$w index @0,0] "%d.%d" y dummy ; incr y -1
  $t yview $y
}

# Turn vertical grid on. Side indicates where to put it.
proc th_Text_toggle_grid_y {w {side left}} {
  if {[winfo manager $w] != "pack"} {
    set tl "[set w].gridy"
    set g "[set tl].g"
  } else {
    set tl ""
    set g "[set w]_gridy"}

  global TH
  if {[winfo exists $g]} {
# turn grid off
    set TH(Grid_Y,$w) 0

# Reset w's scrollcommand to its scrollbar or nothing if it didn't have one.
    if {[scan [$g cget -yscrollcommand] "%s set" sc] >= 0} {
      $w configure -yscrollcommand "$sc set"
    } else {$w configure -yscrollcommand {}}

    if {$tl != ""} {destroy $tl} else {destroy $g}
  } else {
# turn grid on
    set TH(Grid_Y,$w) 1

    scan [$w index end] "%d.%d" endindex dummy
    set width [string length $endindex]
    if {$tl != ""} {
      toplevel $tl
      wm protocol $tl WM_DELETE_WINDOW { }
      wm transient $tl [winfo toplevel $w]
    }
    text $g -relief ridge -wrap none -height [$w cget -height] \
      -font [$w cget -font] -width $width -borderwidth 2
    
    if {$tl != ""} {pack $g -expand yes -fill x
    } else {
      set w_side [lindex [pack info $w] end]
      eval pack $g -anchor w [lrange [pack info $w] 6 15] -expand 0 -side $side -before $w
      switch [list $w_side $side] {
        {top bottom} - {left right} - {bottom top} - {right left} {
          pack $g -after $w -side $w_side
      }}

      set fill [lindex [pack info $w] 7]
      if {$fill == "both"} {pack $g -fill y
      } elseif {$fill == "x"} {pack $g -fill none}}

# Disable scanning on g.
    bindtags $g "$g ."

# Fill g with numbers.
    scan [$w index end] "%d." lines
    for {set line 1} {$line <= $lines} {incr line} {
      $g insert end "$line\n"}
    $g configure -state disabled

# Tie w's yscrollcommand over to g.
    $g yview [$w index @0,0]
    if {[scan [$w cget -yscrollcommand] "%s set" sc] >= 0} {
# Give g the responsibility of moving w's scrollbar.
      $g configure -yscrollcommand "$sc set"
    }
    $w configure -yscrollcommand "th_Text_yview $w $g"
}}
