#!/usr/bin/rhswish -f

# Help tool
# (C) Copyright 1994 by Red Hat Software

if {[catch set env(CONTROL_PANEL_LIB_DIR)] != 0} {
    set env(CONTROL_PANEL_LIB_DIR) /usr/lib/rhs/control-panel
}
if {[catch {source $env(CONTROL_PANEL_LIB_DIR)/dialog.tcl}] != 0} {
    puts "Couldn't load dialog.tcl"
    puts "Start from control-panel or set environment variable"
    puts "CONTROL_PANEL_LIB_DIR to the control-panel library dir."
    puts "(normally this is /usr/lib/rhs/control-panel)"
    exit 0
}
if {[catch {source $env(CONTROL_PANEL_LIB_DIR)/bindings.tcl}] != 0} {
    puts "Couldn't load bindings.tcl"
    puts "Start from control-panel or set environment variable"
    puts "CONTROL_PANEL_LIB_DIR to the control-panel library dir."
    puts "(normally this is /usr/lib/rhs/control-panel)"
    exit 0
}

#########################################################
## @@ Random Data

set search_program "helpme"

set path(doc) "/usr/doc:/usr/local/doc"
set path(info) "/usr/info:/usr/local/info"
set path(man) "/usr/man:/usr/X11/man:/usr/local/man"
set path(mansect) "1:2:3:4:5:6:7:8:9:l:n:x"

set search_doc 1
set search_info 1
set search_man 1
set section_limit 0

set case_sensitive 0

## set up command names
set command(doc) "xterm -e sh -c \"zmore %s\""
if {[file executable "/usr/bin/tkinfo"]} {
    set command(info) "/usr/bin/tkinfo %s"
} else {
    set command(info) "xterm -e info -f %s"
}
if {[file executable "/usr/bin/tkman"]} {
    set command(man) "/usr/bin/tkman %s"
} else {
    set command(man) "xterm -e /usr/bin/man %s"
}

#########################################################
## @@ User interface

frame .listf

frame .main -relief sunken -borderwidth 2
listbox .list -font fixed -yscrollcommand ".sb set" -setgrid 1 -exportselection 0 \
    -relief sunken
scrollbar .sb -command ".list yview"
pack .list -side left -expand true -fill both -in .main
pack .sb -side left -fill y -in .main

frame .entryf -borderwidth 2
checkbutton .case -text "Case Sensitive" -variable case_sensitive
label .entryl -text "Search Pattern:" -anchor w -borderwidth 2
entry .entry -font fixed -relief sunken -borderwidth 2
pack .case .entryl -side left -in .entryf
pack .entry -expand true -fill x -side left -in .entryf

frame .buttons
button .configure -text "Configure" -width 10 -command button_configure
button .search -text "Search" -width 10 -command button_search
button .quit -text "Quit" -width 10 -command button_quit
pack .configure -side left -ipady 1 -in .buttons
pack .search -side left -expand true -ipady 1 -in .buttons
pack .quit -side left -ipady 1 -in .buttons

pack .main -side top -fill both -expand true
pack .entryf -side top -fill x -padx 4
pack .buttons -side top -fill x -padx 4 -pady 4

wm title . "Help Tool"
update
scan [wm geometry .] "%d%*c%d" xmin ymin
wm minsize . $xmin $ymin

## Set some bindings

tk_listboxSingleSelect .list
bind .list <Double-Button-1> "
    .list select clear
    .list select from \[.list nearest %y\]
    view_selected_entry
"
set_emacs_entry_bindings .entry
bind .entry <Return> null
focus .entry

## End of main user interface
###########################################################
## @@ User Interface Callback functions

proc null {} {}

proc button_configure {} {
    global path search_doc search_info search_man section_limit

    toplevel .c
    wm title .c "Configure"

    frame .c.docf
    frame .c.infof
    frame .c.manf
    frame .c.mansectf

    checkbutton .c.docck -variable search_doc -text "Random Docs" -width 15 -anchor w
    checkbutton .c.infock -variable search_info -text "Info Pages" -width 15 -anchor w
    checkbutton .c.manck -variable search_man -text "Man Pages" -width 15 -anchor w
    checkbutton .c.mansectck -variable section_limit -text "Man Sections" -width 15 -anchor w

    entry .c.doce -font fixed -relief sunken
    entry .c.infoe -font fixed -relief sunken
    entry .c.mane -font fixed -relief sunken
    entry .c.mansecte -font fixed -relief sunken

    set_emacs_entry_bindings .c.doce
    bind .c.doce <Return> null
    set_emacs_entry_bindings .c.mane
    bind .c.mane <Return> null
    set_emacs_entry_bindings .c.infoe
    bind .c.infoe <Return> null
    set_emacs_entry_bindings .c.mansecte
    bind .c.mansecte <Return> null
    
    .c.doce insert 0 $path(doc)
    .c.infoe insert 0 $path(info)
    .c.mane insert 0 $path(man)
    .c.mansecte insert 0 $path(mansect)

    pack .c.docck -side left -in .c.docf
    pack .c.doce -expand true -fill x -side left -padx 2 -in .c.docf
    pack .c.infock -side left -in .c.infof
    pack .c.infoe -expand true -fill x -side left -padx 2 -in .c.infof
    pack .c.manck -side left -in .c.manf
    pack .c.mane -expand true -fill x -side left -padx 2 -in .c.manf
    pack .c.mansectck -side left -in .c.mansectf
    pack .c.mansecte -expand true -fill x -side left -padx 2 -in .c.mansectf

    message .c.notice -justify left -aspect 10000 -text \
	"If \"Man Sections\" is not selected, all sections are searched"

    button .c.ok -text "OK" -command finish_config -width 10

    pack .c.docf .c.infof .c.manf .c.notice .c.mansectf \
	-side top -expand true -fill x -padx 2 -pady 1 -in .c

    pack .c.ok -side top -padx 2 -pady 1 -in .c

    update
    wm minsize .c [winfo width .c] [winfo height .c]
    wm maxsize .c 1000 [winfo height .c]
}

proc finish_config {} {

    global path

    set path(doc) [.c.doce get]
    set path(man) [.c.mane get]
    set path(info) [.c.infoe get]
    set path(mansect) [.c.mansecte get]

    destroy .c
}

proc button_quit {} {
    exit 0
}

proc button_search {} {
    global case_sensitive search_program map
    global path search_doc search_info search_man section_limit
    
    set search_pattern [.entry get]

    ## Erase list
    .list delete 0 end

    ## Put up notice
    toplevel .searching
    wm withdraw .searching
    wm title .searching "Searching"
    message .searching.m -text "\nSearching...\n" -aspect 10000
    button .searching.c -text "Cancel"
    pack .searching.m -side top
    pack .searching.c -side top -padx 4 -pady 4
    center_dialog .searching
    update

    ## Run command
    if {$case_sensitive == 1} {
	set opts ""
    } else {
	set opts "-n"
    }
    if {$search_doc == 1} {
	set opts "$opts -d $path(doc)"
    } else {
	set opts "$opts -d \"\""
    }
    if {$search_info == 1} {
	set opts "$opts -i $path(info)"
    } else {
	set opts "$opts -i \"\""
    }
    if {$search_man == 1} {
	set opts "$opts -m $path(man)"
    } else {
	set opts "$opts -m \"\""
    }
    if {$section_limit == 1} {
	set opts "$opts -c $path(mansect)"
    }
    set fd [open "| $search_program $opts '$search_pattern'" r]
    addinput $fd "search_program_input %E %F"
    .search configure -state disabled
    .searching.c configure -command "finish_searching $fd"
}

proc search_program_input {events fileid} {
    global map

    if {[gets $fileid line] < 0} {
	finish_searching $fileid
    } else {
	## Put output in list and array
	set f [lindex $line 1]
	set t [lindex $line 0]
	set map($f) $t
	.list insert end $f
    }
}

proc finish_searching {fileid} {
    removeinput $fileid
    destroy .searching
    .search configure -state active
}

proc view_selected_entry {} {
    global map command

    set f [.list get [.list curselection]]
    set t $map($f)

    if {$t == "man:"} {
	set c [format $command(man) $f]
    } elseif {$t == "info:"} {
	# This magic uses the first info file in a series
	regsub {(.*)(-[0-9]+)([\.gz])} $f {\1\3} nf
	set c [format $command(info) $nf]
    } else {
	set c [format $command(doc) $f]
    }

    eval exec "$c &"
}

## End of user interface callback functions
#############################################
## @@ main program

