# incremental search panel
# based on code from gitk, Copyright (C) Paul Mackerras

class searchbar {

field w
field ctext

field searchstring   {}
field regexpsearch
field default_regexpsearch
field casesensitive
field default_casesensitive
field smartcase
field searchdirn     -forwards

field history
field history_index

field smarktop
field smarkbot

constructor new {i_w i_text args} {
	global use_ttk NS
	set w      $i_w
	set ctext  $i_text

	set default_regexpsearch [is_config_true gui.search.regexp]
	set smartcase [is_config_true gui.search.smartcase]
	if {$smartcase} {
		set default_casesensitive 0
	} else {
		set default_casesensitive 1
	}

	set history [list]

	${NS}::frame  $w
	${NS}::label  $w.l       -text [mc Find:]
	tentry  $w.ent -textvariable ${__this}::searchstring -background lightgreen
	${NS}::button $w.bn      -text [mc Next] -command [cb find_next]
	${NS}::button $w.bp      -text [mc Prev] -command [cb find_prev]
	${NS}::checkbutton $w.re -text [mc RegExp] \
		-variable ${__this}::regexpsearch -command [cb _incrsearch]
	${NS}::checkbutton $w.cs -text [mc Case] \
		-variable ${__this}::casesensitive -command [cb _incrsearch]
	pack   $w.l   -side left
	pack   $w.cs  -side right
	pack   $w.re  -side right
	pack   $w.bp  -side right
	pack   $w.bn  -side right
	pack   $w.ent -side left -expand 1 -fill x

	eval grid conf $w -sticky we $args
	grid remove $w

	trace add variable searchstring write [cb _incrsearch_cb]
	bind $w.ent <Return> [cb find_next]
	bind $w.ent <Shift-Return> [cb find_prev]
	bind $w.ent <Key-Up>   [cb _prev_search]
	bind $w.ent <Key-Down> [cb _next_search]
	
	bind $w <Destroy> [list delete_this $this]
	return $this
}

method show {} {
	if {![visible $this]} {
		grid $w
		$w.ent delete 0 end
		set regexpsearch  $default_regexpsearch
		set casesensitive $default_casesensitive
		set history_index [llength $history]
	}
	focus -force $w.ent
}

method hide {} {
	if {[visible $this]} {
		focus $ctext
		grid remove $w
		_save_search $this
	}
}

method visible {} {
	return [winfo ismapped $w]
}

method editor {} {
	return $w.ent
}

method _get_new_anchor {} {
	# use start of selection if it is visible,
	# or the bounds of the visible area
	set top    [$ctext index @0,0]
	set bottom [$ctext index @0,[winfo height $ctext]]
	set sel    [$ctext tag ranges sel]
	if {$sel ne {}} {
		set spos [lindex $sel 0]
		if {[lindex $spos 0] >= [lindex $top 0] &&
		    [lindex $spos 0] <= [lindex $bottom 0]} {
			return $spos
		}
	}
	if {$searchdirn eq "-forwards"} {
		return $top
	} else {
		return $bottom
	}
}

method _get_wrap_anchor {dir} {
	if {$dir eq "-forwards"} {
		return 1.0
	} else {
		return end
	}
}

method _do_search {start {mlenvar {}} {dir {}} {endbound {}}} {
	set cmd [list $ctext search]
	if {$mlenvar ne {}} {
		upvar $mlenvar mlen
		lappend cmd -count mlen
	}
	if {$regexpsearch} {
		lappend cmd -regexp
	}
	if {!$casesensitive} {
		lappend cmd -nocase
	}
	if {$dir eq {}} {
		set dir $searchdirn
	}
	lappend cmd $dir -- $searchstring
	if {[catch {
		if {$endbound ne {}} {
			set here [eval $cmd [list $start] [list $endbound]]
		} else {
			set here [eval $cmd [list $start]]
			if {$here eq {}} {
				set here [eval $cmd [_get_wrap_anchor $this $dir]]
			}
		}
	} err]} { set here {} }
	return $here
}

method _incrsearch_cb {name ix op} {
	after idle [cb _incrsearch]
}

method _incrsearch {} {
	$ctext tag remove found 1.0 end
	if {[catch {$ctext index anchor}]} {
		$ctext mark set anchor [_get_new_anchor $this]
	}
	if {$smartcase} {
		if {[regexp {[[:upper:]]} $searchstring]} {
			set casesensitive 1
		}
	}
	if {$searchstring ne {}} {
		set here [_do_search $this anchor mlen]
		if {$here ne {}} {
			$ctext see $here
			$ctext tag remove sel 1.0 end
			$ctext tag add sel $here "$here + $mlen c"
			#$w.ent configure -background lightgreen
			$w.ent state !pressed
			_set_marks $this 1
		} else {
			#$w.ent configure -background lightpink
			$w.ent state pressed
		}
	}
}

method _save_search {} {
	if {$searchstring eq {}} {
		return
	}
	if {[llength $history] > 0} {
		foreach {s_regexp s_case s_expr} [lindex $history end] break
	} else {
		set s_regexp $regexpsearch
		set s_case   $casesensitive
		set s_expr   ""
	}
	if {$searchstring eq $s_expr} {
		# update modes
		set history [lreplace $history end end \
				[list $regexpsearch $casesensitive $searchstring]]
	} else {
		lappend history [list $regexpsearch $casesensitive $searchstring]
	}
	set history_index [llength $history]
}

method _prev_search {} {
	if {$history_index > 0} {
		incr history_index -1
		foreach {s_regexp s_case s_expr} [lindex $history $history_index] break
		$w.ent delete 0 end
		$w.ent insert 0 $s_expr
		set regexpsearch $s_regexp
		set casesensitive $s_case
	}
}

method _next_search {} {
	if {$history_index < [llength $history]} {
		incr history_index
	}
	if {$history_index < [llength $history]} {
		foreach {s_regexp s_case s_expr} [lindex $history $history_index] break
	} else {
		set s_regexp $default_regexpsearch
		set s_case   $default_casesensitive
		set s_expr   ""
	}
	$w.ent delete 0 end
	$w.ent insert 0 $s_expr
	set regexpsearch $s_regexp
	set casesensitive $s_case
}

method find_prev {} {
	find_next $this -backwards
}

method find_next {{dir -forwards}} {
	focus $w.ent
	$w.ent icursor end
	set searchdirn $dir
	$ctext mark unset anchor
	if {$searchstring ne {}} {
		_save_search $this
		set start [_get_new_anchor $this]
		if {$dir eq "-forwards"} {
			set start "$start + 1c"
		}
		set match [_do_search $this $start mlen]
		$ctext tag remove sel 1.0 end
		if {$match ne {}} {
			$ctext see $match
			$ctext tag add sel $match "$match + $mlen c"
		}
	}
}

method _mark_range {first last} {
	set mend $first.0
	while {1} {
		set match [_do_search $this $mend mlen -forwards $last.end]
		if {$match eq {}} break
		set mend "$match + $mlen c"
		$ctext tag add found $match $mend
	}
}

method _set_marks {doall} {
	set topline [lindex [split [$ctext index @0,0] .] 0]
	set botline [lindex [split [$ctext index @0,[winfo height $ctext]] .] 0]
	if {$doall || $botline < $smarktop || $topline > $smarkbot} {
		# no overlap with previous
		_mark_range $this $topline $botline
		set smarktop $topline
		set smarkbot $botline
	} else {
		if {$topline < $smarktop} {
			_mark_range $this $topline [expr {$smarktop-1}]
			set smarktop $topline
		}
		if {$botline > $smarkbot} {
			_mark_range $this [expr {$smarkbot+1}] $botline
			set smarkbot $botline
		}
	}
}

method scrolled {} {
	if {$searchstring ne {}} {
		after idle [cb _set_marks 0]
	}
}

}
