# Copyright (c) 2000, Red Hat, Inc.
# 
# This file is part of Source-Navigator.
# 
# Source-Navigator 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.
# 
# Source-Navigator 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.
# 
# You should have received a copy of the GNU General Public License along
# with Source-Navigator; see the file COPYING.  If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA.
# 
# grep.tcl - Operations using the familiar grep(1) command.
# Copyright (C) 1998 Cygnus Solutions.

# Get a search string & execute a grep shell command.
#
proc sn_grep {{sel 0} {ptrn ""}} {
	global tkeWinNumber
	global sn_options

	if {$ptrn == ""} {
		set xstr ""
		catch {set xstr [string trim [selection get]]}
	} else {
		set xstr $ptrn
	}
	set xstr [Grep& @@ FormatPattern $xstr]

	set s [find_reusable_window "grep-"]
	if {$s == ""} {
		incr tkeWinNumber
		set s ".sn-grep-$tkeWinNumber"
		sn_create_window $s 1
		$s withdraw
		
		#add hold button at the left side of grep to hold/close window
		#after choosing an item
		button $s.exp.hold \
				-takefocus 0 \
				-text [get_indep String HoldWindow]\
				-image hold_off_image\
				-command " "
		bind $s.exp.hold <Any-ButtonPress> \
			"if {%b == 1} {grep_toggle_hold $s $s.exp.hold}"
		balloon_bind_info $s.exp.hold [get_indep String HoldWindowINFO]
		upvar #0 $s-hold hold
		set hold 0

		frame $s.exp.space -width 3
				 
		pack $s.exp.hold -side left
		pack $s.exp.space -side left

		Grep& $s.grep \
			-symbols "" \
			-symbols_filter "" \
			-menu "" \
			-toolbar $s.exp \
			-mesg_area $s.status.msg \
			-hold $hold
		pack $s.grep -expand y -fill both -side left
		$s move_to_mouse
	}
	if {$xstr != ""} {
		$s.grep config -pattern $xstr
	}
	if {$sel && $xstr != ""} {
		$s.grep ExecGrep
	} else {
		$s.grep SetTitle
	}
	return $s
}

proc sn_grep_from_history {str flt lst highl_pos} {
	global tkeWinNumber
	
	set mwin [MultiWindow& @@ find_Reusable]
	if {![winfo exists $mwin]} {
		#create a new multiple window
		incr tkeWinNumber
		set mwin .multiwindow-$tkeWinNumber
		MultiWindow& $mwin \
			-raise grep
	} else {
		#toggle to grep
		$mwin view grep
	}
	set active_wdg [$mwin ActiveWidget]
	if {[winfo exists $mwin]} {
		$active_wdg DisplayFromHistory $str $flt $lst $highl_pos
	}
}

proc grep_toggle_hold {win btn} {
		upvar #0 $win-hold hold
		if {$hold} {
			$btn config -relief raised -image hold_off_image
			set hold 0
		} else {
			$btn config -relief sunken -image hold_on_image
			set hold 1
		}
		$win.grep config -hold $hold
}

proc sn_grep_edit_file line {
	global sn_options

	watch y

	#make sure we stay in project directory (different interpeters).
	catch {cd $sn_options(sys,project-dir)}
		
	set pars [sn_goto_comp_error_or_grep $line]
	set file [lindex $pars 0]
	set pos [lindex $pars 1]
	
	#be sure that file is not empty, this cause an error
	if {$file == ""} {
		watch n
		return "no"
	}
	sn_log "grep file <$file> line <$pos>"

	set file [sn_convert_FileName $file]
	if {$pars == "" || ![file exists $file] || $pos == ""} {
		bell
		watch n
		return "no"
	}

	sn_edit_file dummy $file $pos
	watch n
	return ""
}

# This function tries to figure out the name of a file
# and position from a line.
proc sn_goto_comp_error_or_grep {sym} {
	global grep_compiled_err_patterns
	global tcl_platform sn_options

	if {$tcl_platform(platform) == "windows" && [string range $sym 1 1] == ":"} {
		set pars [split $sym ":"]
		set file [lindex $pars 0]:[lindex $pars 1]
		set pos  [lindex $pars 2]
		return [list $file $pos]
	}
	
	if {![info exists grep_compiled_err_patterns]} {
		set name [sn_search_file sn_cmp_g.pat]

		set fd [open $name]
		fconfigure $fd -encoding $sn_options(def,system-encoding)
		set lst [read -nonewline $fd]
		set lst [split $lst "\n"]
		close $fd

		set grep_compiled_err_patterns [lmatch -regexp $lst {^[^#]}]
	}

	set file ""
	set line 0
	foreach pat $grep_compiled_err_patterns {
		set sv1 ""
		set sv2 ""
		set mat [regexp -- $pat $sym mat_var sv1 sv2]
		if {$mat} {
			if {[string match {[0-9]*} $sv2]} {
				set file $sv1
				set line $sv2
			} else {
				set file $sv2
				set line $sv1
			}
			# Convert e.g. 123,35 to 123.35!
			regsub {,} $line {.} line
			return [list $file $line]
		}
	}
	return ""
}

