# search.tcl --
#
# This script creates a collection of procedures that
# allow you to load a file into a text widget, then perform searches
# on that file.
#
# SCCS: @(#) search.tcl 1.4 96/02/16 10:49:12
# time: 9:06 morning 22/nov/1997 Alma-Ata Kz

# textLoadFile --
# This procedure below loads a file into a text widget, discarding
# the previous contents of the widget. Tags for the old widget are
# not affected, however.
#
# Arguments:
# w -		The window into which to load the file.  Must be a
#		text widget.
# file -	The name of the file to load.  Must be readable.

proc textLoadFile {w file} {
    set f [open $file]
    $w delete 1.0 end
    while {![eof $f]} {
	$w insert end [read $f 10000]
    }
    close $f
}

# textSearch --
# Search for all instances of a given string in a text widget and
# apply a given tag to each instance found.
#
# Arguments:
# w -		The window in which to search.  Must be a text widget.
# string -	The string to search for.  The search is done using
#		exact matching only;  no special characters.
# tag -		Tag to apply to each instance of a matching string.

proc textSearch {w string tag} {
    $w tag remove $tag 0.0 end
    if {$string == ""} {
	return
    }
    set cur 1.0
    while 1 {
	set cur [$w search -count length $string $cur end]
	if {$cur == ""} {
	    break
	}
	$w tag add $tag $cur "$cur + $length char"
	set cur [$w index "$cur + $length char"]
    }
}

proc textHiliteLineNo {w LineNo tag} {
    $w tag remove $tag 0.0 end
    if {$LineNo == ""} {
	return
    }
    set cur $LineNo.0

    $w tag add $tag $cur "$cur + 1 line"
}



# textToggle --
# This procedure is invoked repeatedly to invoke two commands at
# periodic intervals.  It normally reschedules itself after each
# execution but if an error occurs (e.g. because the window was
# deleted) then it doesn't reschedule itself.
#
# Arguments:
# cmd1 -	Command to execute when procedure is called.
# sleep1 -	Ms to sleep after executing cmd1 before executing cmd2.
# cmd2 -	Command to execute in the *next* invocation of this
#		procedure.
# sleep2 -	Ms to sleep after executing cmd2 before executing cmd1 again.

proc textToggle {cmd1 sleep1 cmd2 sleep2} {
    catch {
	eval $cmd1
	after $sleep1 [list textToggle $cmd2 $sleep2 $cmd1 $sleep1]
    }
}

#-----------------------------------------------------------------------------
# Set up display styles for text highlighting.
#-----------------------------------------------------------------------------
proc textSetupFlash {w} {
  if {[winfo depth $w] > 1} {
    textToggle "$w tag configure search -background \
	    #ce5555 -foreground white" 800 "$w tag configure \
	    search -background {} -foreground {}" 200
  } else {
    textToggle "$w tag configure search -background \
	    black -foreground white" 800 "$w tag configure \
	    search -background {} -foreground {}" 200
  }
}

