#******************************************************************************
#***
#*** This file is part of XTeXShell; see file xtexsh for details
#*** Version 0.91 (21.2.94)
#***
#******************************************************************************

proc HyperHelp {keyword} {

#*****************************************************************************
#*** Hypertext Help System
#***
#*** Open a new help window and display the help page for the entry keyword
#*** If keyword == "", display index
#*** If last char of keyword is _, then keyword is the name of a bitmap to
#***      be display
#*****************************************************************************

       global      help_win  hyphelp_name  hyphelp_geo
       global      helplist

#*** Open help window

       set         help_win [CreateTopWin hyphelp "CREATE"]
       set         c $hyphelp_name.c

       wm title    $help_win "LaTeX Syntax Help"
       wm iconname $help_win "LaTeX Syntax Help"

       frame       $help_win.but       -relief raised -borderwidth 1
       pack        $help_win.but       -side bottom -fill x

       button      $help_win.but.idx   -text "Index"   -command {WriteHelp "Index"}
       button      $help_win.but.last  -text "Last"    -command {lvarpop helplist; WriteHelp [lvarpop helplist]}

       button      $help_win.but.done  -text "Done"    -command {destroy $help_win}
       pack        $help_win.but.done $help_win.but.last $help_win.but.idx   -side left -fill x -padx 3m -pady 1m -ipadx 0.6m

       scrollbar   $help_win.ys        -command "$c yview" -relief sunken
       pack        $help_win.ys        -side right -fill y

       text        $c                  -relief raised -bd 2 -yscrollcommand "$help_win.ys set" -setgrid true -width 80 -height 32
       pack        $c                  -side left -fill both -expand yes

#*** Set up fonts and colors

       global normal_font normall_font italicl_font boldl_font courier_font courierl_font terml_font
       global courierboldl_font bold_font

       $c tag configure normal         -font $normal_font
       $c tag configure italic         -font $italicl_font
       $c tag configure bold           -font $boldl_font
       $c tag configure header         -font $bold_font
       $c tag configure name           -font $normal_font
       $c tag configure synop          -font $courierboldl_font
       $c tag configure section        -font $boldl_font
       $c tag configure terminal       -font $terml_font
       $c tag configure example        -font $courier_font
       $c tag configure line           -font $courierl_font
       $c tag configure underline      -font $normal_font -underline on
       $c tag configure hyper          -font $normal_font -foreground red -underline 1

#*** Set key bindings

       focus       $help_win

       bind $c <Button-3>   { %W index @%X,%Y;
                              set word [%W get "@%x,%y wordstart"  "@%x,%y wordend"]
                              WriteHelp $word
                            }

       bind $c <Control-F1> { set word [%W get "insert wordstart" "insert wordend"]
                              WriteHelp $word
                            }
       bind $c <Any-Key>    { }

       bind $c <2>          {%W scan mark -%y}
       bind $c <B2-Motion>  {%W scan dragto -%y}

#*** Fill Window with help page

       update
       WriteHelp  $keyword
}


proc FindIndex {keyword} {

#*** Search keyword in index file and return File Position. If keyword
#*** is not in index file, return -1
#*** else filename is in help_file, position in help_pos

       global HelpIndexName
       global xtexsh_path help_file help_fpos

       set infile  [open $HelpIndexName  "r"]

       while {![eof $infile]} {
               gets $infile inline
               set word [lvarpop inline]
               if [cequal $word $keyword] {
                       set help_file [format "$xtexsh_path/help/%s" [lvarpop inline]]
                       set help_fpos [lvarpop inline]
                       return 0
               }
       }
       close $infile;                                  #*** Entry was not found
       return -1
}


proc WriteHelp {keyword} {

#*** Display Help for keyword in window help_win
#*** If keyword=="Index", display index

       global  HelpIndexName
       global  help_win
       global  indent listtype helplist
       global  boldl_font
       global  help_file help_fpos
       global  xtexsh_path

       set     W $help_win.c
       set     HelpIndexName   "$xtexsh_path/help/help.index"

#*** Does keyword make sense ?

       if {[cequal "" $keyword]} {return}

#*** Is last character of keyword "_" ? Then display a bitmap

       if {[cequal "_" [cindex $keyword end]]} {
               BmpHelp [crange $keyword 0 "end-1"]
               return
       }

#*** No, delete old entry and prepare for new entry

       $W delete 0.0 end;                              #*** Delete text in window
       set indent 14
       set indentstr [replicate " " $indent]

       lvarpush helplist $keyword

       if {[cequal "" $keyword]} {set keyword "Index"}

#*** Display the index ?

       if {[cequal "Index" "$keyword"]} {
               set fchar " "
               set infile [open $HelpIndexName "r"]
               while {![eof $infile]} {                #*** Read all lines of help file
                       gets $infile inline
                       set inline [lindex $inline 0];  #*** Get first word in line
                       set fc [string toupper [cindex $inline 0]]
                       if {[cequal $fc "_"]} {continue}
                       if {![cequal $fc $fchar]} {
                               AddHelpLine $W "" "normal"
                               AddHelpLine $W "$fc" "bold"
                               set fchar $fc
                               if {[cequal $fc "E"]} { #*** E is 1/7th of the alphabet
                                       update;         #*** print what we've got so far that the user
                               }                       #*** doesn't fall asleep...
                       }
                       HypInsert $W $indentstr normal;         #*** And append to help window
                       HypInsert $W "$inline\n" "hyper";       #*** Better us AddHelpLine, but this is too slow
               }
               close $infile;                          #*** Close file and return
               return
       }

#*** No, is there an entry for keyword in the index file ?

       if {-1==[FindIndex $keyword]} {
               set retval [DisplayQuest "No Entry found for keyword:\n$keyword" "$boldl_font" "Cancel" "Index" "Help"]
               switch $retval {
                       "1"  {destroy $help_win; return}
                       "2"  {WriteHelp "Index"; return}
                       "3"  {WriteHelp "_helpxtexhelp"; return}
               }
       }

       set Mode "normal"
       set LinePat "_____________________________________________________________"

#*** Ok, diplay help for keyword.

       set infile  [open $help_file  "r"]
       set lineone 0
       seek $infile $help_fpos
       for {set endentry 0} {$endentry==0 && ![eof $infile]} { } {
               gets $infile inline
               switch -regexp -- [lindex $inline 0] {
                       ":endentry"   { set endentry 1; continue }
                       ":header"     { HypInsert $W "\n" normal
                                       set Mode "header"
                                       continue;
                                     }
                       ":name"       { set Mode "name"
                                       HypInsert $W "$LinePat\n" line
                                       set lineone 1
                                       HypInsert $W "\n NAME\n\n"  section
                                       continue
                                     }
                       ":synop"      { set Mode "synop"
                                       if {!$lineone} {
                                               HypInsert $W "$LinePat\n" line
                                               set lineone 1
                                       }
                                       HypInsert $W "\n SYNOPSIS\n\n" section
                                       continue
                                     }
                       ":descr"      { set Mode "normal"
                                       HypInsert $W "$LinePat\n" line
                                       HypInsert $W "\n DESCRIPTION\n\n" section
                                       update
                                       continue
                                     }
                       ":tt"         { set Mode "example"
                                       continue
                                     }
                       ":example"    { set Mode "example"
                                       HypInsert $W "\n\n EXAMPLE\n\n" section
                                       continue
                                     }
                       ":ul"         { set listtype "U"
                                       HypInsert $W "\n" normal
                                       set indent [expr $indent+12]
                                       continue
                                     }
                       ":eul"        { set indent [expr $indent-12]
                                       HypInsert $W "\n" section
                                       continue
                                     }
                       ":dl"         { set listtype "D"
                                       HypInsert $W "\n" normal
                                       set indent [expr $indent+6]
                                       continue
                                     }
                       ":edl"        { set indent [expr $indent-6]
                                       HypInsert $W "\n" section
                                       continue
                                     }
                       ":el"         { set listtype "E"
                                       HypInsert $W "\n" normal
                                       set indent [expr $indent+6]
                                       continue
                                     }
                       ":eel"        { set indent [expr $indent-6]
                                       HypInsert $W "\n" section
                                       continue
                                     }
                       default       { AddHelpLine $W "$inline" $Mode; continue }
               }
      }
      close $infile
}

proc    AddHelpLine {W line Mode} {

#*** Add line to help-window, look for  emphasized, bold and hypertext commands

       global indent listtype

#*** Calculate indentation and generate List Entries

       set cpos [string first ":li " $line]

       if {$cpos < 0} {
               HypInsert $W [replicate " " $indent] normal
       } else {
                ctoken line " "
                set line [string trimleft $line]
                HypInsert $W [replicate " " [expr $indent-6]] normal
                switch $listtype {
                   "U"  { HypInsert $W "q " terminal }
                   "E"  { HypInsert $W "      " normal}
                   "D"  { HypInsert $W [ctoken line " "] bold }
               }
       }

#*** Run over string and handle formatting commands

       while {![cequal "" $line]} {
               set cpos [string first ":" $line]
               if {$cpos == -1 } {
                       HypInsert $W $line $Mode
                       set line ""
                       break;
               }
               if {$cpos > 0} {
                       HypInsert $W [crange $line 0 [expr $cpos-1]] $Mode
                       set line [crange $line $cpos end]
               }

#*** The first character is a :. Check for special formatting commands

               set token [ctoken line " "]

               switch $token  {
                       ":em"    { set Smode "italic" }
                       ":hl"    { set Smode "hyper" }
                       ":bold"  { set Smode "bold" }
                       default  { set Smode $Mode; set line "$token $line" }
               }

#*** The next word has special attributes. Get and print it

               set token [ctoken line " "]
               HypInsert $W $token "$Smode"
       }
       HypInsert $W "\n" $Mode
}


proc HypInsert {w text args} {

#*** HypInsert inserts text into a given text widget and
#*** applies one or more tags to that text.  The arguments are:

       set start [$w index insert]
       $w insert insert $text

       foreach tag [$w tag names $start] {
               $w tag remove $tag $start insert
       }
       foreach i $args {
               $w tag add $i $start insert
       }
}


proc ManHelp {command} {

#*** Show manpage for command

       global manhelp_geo

       exec xterm -g $manhelp_geo -e man $command &
}


proc BmpHelp {fname} {

#******************************************************************************
#*** Show bitmap file fname in a new canvas window
#******************************************************************************

       global      bmphelp_name bmphelp_geo
       global      xtexsh_path bitmap_win

       set         bitmap_win  [CreateTopWin bmphelp "CREATE"]
       set         c           $bmphelp_name.c

       wm title    $bitmap_win "Help -- LaTeX $fname"
       wm iconname $bitmap_win "Help -- LaTeX $fname"

       frame       $bitmap_win.but      -relief raised -borderwidth 1 -width 10c -height 10c
       pack        $bitmap_win.but      -side bottom -fill x

       button      $bitmap_win.but.ok   -text "Done"    -command {destroy $bitmap_win}
       pack        $bitmap_win.but.ok   -side bottom -fill x -padx 3m -pady 1m

       scrollbar   $bitmap_win.sy       -command "$c yview" -relief sunken
       pack        $bitmap_win.sy       -side right -fill y

       canvas      $c                   -yscroll "$bitmap_win.sy set" -relief flat
       pack        $c                   -side left -fill both -expand yes

#*** Read and display bitmap

       $c create bitmap  2 2  -bitmap "@$xtexsh_path/bitmaps/$fname" -anchor nw -tags item
       $c config -scrollregion [$c bbox all]

       focus       $bitmap_win
}