#
# Copyright (C) 1999  Noriaki TANAKA
#                     Motoyuki Kasahara
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#

# Case sensitivity.
set finder_case 0

# Direction to find a next pattern.
set finder_direction forward

# Pattern to find.
set finder_pattern ""

# Where it starts to find a pattern.
set finder_current_index 1.0

#
# Make finder window.
#
proc finder_make_window {} {
    global finder_case
    global finder_direction
    global finder_pattern
    global finder_current_index

    #
    # Toplevel.
    #
    if {![catch {winfo .finder}]} {
	destroy .finder
    }
    toplevel .finder -class Popup
    wm title .finder [_ "find word in text"]
    wm withdraw .finder
    set x [expr [winfo rootx .] + 24]
    set y [expr [winfo rooty .] + 24]
    wm geometry .finder +$x+$y
    wm deiconify .finder

    #
    # Pattern entry.
    #
    frame .finder.pattern -relief raise
    pack  .finder.pattern -side top -fill x -expand 1 -padx 4 -pady 4
    label  .finder.pattern.label -text [_ "Pattern: "]
    pack .finder.pattern.label -side left -anchor w
    entry .finder.pattern.entry -relief sunken -borderwidth 2 \
	    -textvariable finder_pattern -width 20
    pack .finder.pattern.entry -side left -fill both -expand 1 -padx 4 -pady 4
    .finder.pattern.entry icursor end
    focus .finder.pattern.entry

    #
    # Case sensitivity.
    #
    frame .finder.case
    pack  .finder.case -side top -fill x -expand 1 -anchor w -padx 4 -pady 4
    label .finder.case.label -text [_ "Case Sensitive: "]
    pack .finder.case.label -side left
    radiobutton .finder.case.yes -variable finder_case \
	    -text [_ "Yes"] -value 1 -width 8
    pack .finder.case.yes -side left -expand 1 -anchor w
    radiobutton .finder.case.no -variable finder_case \
	    -text [_ "No"] -value 0 -width 8
    pack .finder.case.no -side left -expand 1 -anchor w

    #
    # Direction.
    #
    frame .finder.direction
    pack  .finder.direction -side top -fill x -expand 1 -anchor w \
	    -padx 4 -pady 4
    label .finder.direction.label -text [_ "Direction:      "]
    pack .finder.direction.label -side left
    radiobutton .finder.direction.forward -variable finder_direction \
	    -text [_ "Forward"] -value "forward" -width 8
    pack .finder.direction.forward -side left -expand 1 -anchor w
    radiobutton .finder.direction.backword -variable finder_direction \
	    -text [_ "Backward"] -value "backword" -width 8
    pack .finder.direction.backword -side left -expand 1 -anchor w

    #
    # Buttons.
    #
    frame .finder.buttons
    pack  .finder.buttons -fill x -expand 1 -padx 4 -pady 4
    button .finder.buttons.find -width 8 -text [_ "Find"] \
            -command finder_next -default active
    pack .finder.buttons.find -expand 1 -side left
    button .finder.buttons.clear -width 8 -text [_ "Clear"] -command {
	set finder_pattern {}
	set finder_current_index 1.0
	.text.text tag remove sel 1.0 end
    }
    pack .finder.buttons.clear -expand 1 -side left
    button .finder.buttons.cancel -width 8 -text [_ "Cancel"] \
	    -command {destroy .finder}
    pack .finder.buttons.cancel -expand 1 -side left

    bind .finder <Return> finder_next
    bind .finder <Control-m> finder_next
    bind .finder <Control-s> {finder_next forward}
    bind .finder <Control-r> {finder_next backward}
    bind .finder <Escape> {destroy .finder}

    if {$finder_direction == "forward"} {
	set finder_current_index 1.0
    } else {
	set finder_current_index end
    }
    .text.text tag remove sel 1.0 end
}

#
# Find next.
#
proc finder_next {{direction variable}} {
    global finder_case
    global finder_direction
    global finder_pattern
    global finder_current_index
    global tcl_jp

    if {$finder_pattern == ""} {
	output_information [_ "The pattern is empty."]
	return
    }

    .text.text tag remove sel 1.0 end

    if {$direction == "variable"} {
	set direction $finder_direction
    }
    if {$direction == "forward"} {
	if {$finder_case} {
	    set index [.text.text search $finder_pattern \
		    $finder_current_index end]
	} else {
	    set index [.text.text search -nocase $finder_pattern \
		    $finder_current_index end]
	}
    } else {
	if {$finder_case} {
	    set index [.text.text search -backward $finder_pattern \
		    $finder_current_index 1.0]
	} else {
	    set index [.text.text search -backward -nocase $finder_pattern \
		    $finder_current_index 1.0]
	}
    }
    if {$index == ""} {
        output_information [format [_ "Not found \`%s\'."] $finder_pattern]
        return
    }

    # use kstring in case Tcl8.0.x_jp
    if {$tcl_jp} {
	.text.text tag add sel $index \
		"$index + [kstring length $finder_pattern] chars"
    } else {
	.text.text tag add sel $index \
		"$index + [string length $finder_pattern] chars"
    }
    .text.text see $index

    if {$direction == "forward"} {
        set finder_current_index "$index + 1 chars"
    } else {
        set finder_current_index "$index - 1 chars"
    }

    output_information [format [_ "Found \`%s\'."] $finder_pattern]
}
