set __help_loading 0
############################################################
# Create the help page
# arguments - none
# return    - nothing
############################################################
proc help`helpOnHelp {} {
  global __help_headers __help_history __help_history_index __help_loading
  global __help_grab __SN __BITMAPDIR argv
  
  if {[winfo exist .manpage]} {
    wm deiconify .manpage
    raise .manpage
    if {[grab current .] != ""} {
      set __help_grab [grab current .]
      grabSet .manpage
    }
    return
  }

  if {${__help_loading}} {
    wm deiconify .wait
    raise .wait
    return
  } else {
    set __help_loading 1
  }
  # creating the please wait window
  toplevel .wait
  label .wait.icon -bitmap info
  label .wait.label -text "Loading help,\nplease wait..." \
      -font "-*-helvetica-medium-r-*-*-20-*-*-*-*-*-*-*"
  pack .wait.icon .wait.label -side left -padx  10
  wm withdraw .wait
  update idletasks
  set x [expr [winfo screenwidth .wait]/2 - [winfo reqwidth .wait]/2 \
	     - [winfo vrootx [winfo parent .wait]]]
  set y [expr [winfo screenheight .wait]/2 - [winfo reqheight .wait]/2 \
	     - [winfo vrooty [winfo parent .wait]]]
  wm geom .wait +$x+$y
  wm deiconify .wait
  update
  toplevel .manpage
  wm title .manpage "Dotfile Help"
  if {[grab current .] != ""} {
    set __help_grab [grab current .]
    grabSet .manpage
  }

  ### Creating the help textbox and the index listbox
  frame .manpage.frame
  scrollbar .manpage.frame.lboxscroll -command ".manpage.frame.lbox yview"
  listbox .manpage.frame.lbox 	-relief raised -borderwidth 2 -width 30 \
    -yscrollcommand ".manpage.frame.lboxscroll set"
  scrollbar .manpage.frame.textscroll -command ".manpage.frame.text yview"
  text .manpage.frame.text -wrap word  \
    -yscrollcommand ".manpage.frame.textscroll set" -width 50 \
    -cursor arrow
    pack .manpage.frame.lbox -fill both -side left
  pack .manpage.frame.textscroll -fill y -side right
  pack .manpage.frame.text -fill both -expand 1

  set __SN(help`text) .manpage.frame.text
  set __SN(help`listbox) .manpage.frame.lbox
  set __SN(help`scroll) .manpage.frame.lboxscroll
  set listbox .manpage.frame.lbox
  set prefix .manpage.frame.text
  #####bind .manpage.frame.lbox <Configure> "helpResize"
  bind $listbox <1> help`indexBrowse
  bindtags $listbox "Listbox $listbox"
  bind $listbox <Configure> "helpResize"
  
  ### source the man definition
  if {[file exists [lindex $argv 1]/generatedHelp]} {
    source [lindex $argv 1]/generatedHelp
  } else {
    source [lindex $argv 0]/generatedHelp
  }
  createHelpPage $prefix
  $prefix configure -state disabled


  ### insert elements into the index list
  foreach elm ${__help_headers} {
    set text [lindex $elm 0]
    set header [lindex $elm 1]
    set location [lindex $elm 2]
    set level [string index $header 1]
    set listboxtext [string range "                                         " \
			 0 [expr ($level-1)*5]]
    append listboxtext $text
    $listbox insert end $listboxtext
  }

  ### create the buttons's
  pack [frame .manpage.buttons] -fill x -side bottom
  button .manpage.buttons.back -bitmap @$__BITMAPDIR/Left -command help`back
  button .manpage.buttons.forward -bitmap @$__BITMAPDIR/Right \
      -command help`forward 
  button .manpage.buttons.ok  -text "Close" -command {
    global __help_grab
    wm iconify .manpage
    if {[info exists __help_grab]} {
      grabSet [set __help_grab]
      unset __help_grab
    }
  }
  frame .manpage.buttons.dummy
  pack .manpage.buttons.ok -side left
  pack .manpage.buttons.dummy -padx 40 -side left
  pack .manpage.buttons.back .manpage.buttons.forward \
      -side left -padx 10
  .manpage.buttons.forward configure -state disabled
  .manpage.buttons.back configure -state disabled
  set __SN(help`back) .manpage.buttons.back
  set __SN(help`forward) .manpage.buttons.forward

  ### pack the frame with the textboxes.
  ### NOTE it's necesary to wait until now, to get packing right.
  pack .manpage.frame -expand 1 -fill both

  ### create the search entry
  label .manpage.buttons.label -text "Search String: "
  entry .manpage.buttons.search -textvariable __help_search 
  button .manpage.buttons.up -bitmap @$__BITMAPDIR/Up \
      -command "__help_search backwards"
  button .manpage.buttons.down -bitmap @$__BITMAPDIR/Down \
      -command "__help_search forwards"
  bind .manpage.buttons.search <Return> "__help_search forwards"
  bind .manpage.buttons.search <KP_Enter> __help_search
  pack .manpage.buttons.down .manpage.buttons.up .manpage.buttons.search .manpage.buttons.label   -side right -padx 10

  ### create a handler for window delete
  wm protocol .manpage WM_DELETE_WINDOW {
    global __help_grab
    wm withdraw .manpage
    if {[info exists __help_grab]} {
      grabSet [set __help_grab]
      unset __help_grab
    }
  }

  ### set up the hypertext history
  set __help_history_index 0
  set __help_history {}

  destroy .wait
  set __help_loading 0
}

############################################################
# Change the view in the textbox due to a
# selection in the listbox
# return  - nothing
############################################################
proc help`indexBrowse {} {
  global __help_headers __help_history __help_history_index __SN
  set listbox $__SN(help`listbox)
  set text $__SN(help`text)
  set back $__SN(help`back)
  set forward $__SN(help`forward)
  
  # add the element to the history
  set __help_history [lrange ${__help_history} 0 [expr ${__help_history_index}-1]]
  lappend __help_history [lindex [$text yview] 0]
  incr __help_history_index
  $back configure -state normal
  $forward configure -state disabled

  set index [lindex [lindex ${__help_headers} [$listbox curselection]] 2]
  $text yview $index

  # remove the selection from the listbox
  $listbox selection clear 0 end
}

############################################################
# goto a tag which have been reference with href in the
# html code.
# tag    - the name of the tag
# return - nothing
############################################################
proc help`gotoTag {tag} {
  global __help_ref __help_history __help_history_index __SN __help_loading

  # test wether an other help search is in progress
  if {${__help_loading}} return
  
  # open the help page
  help`helpOnHelp

  set text $__SN(help`text)
  set back $__SN(help`back)
  set forward $__SN(help`forward)
  
  # add the element to the history
  set __help_history [lrange ${__help_history} 0 [expr ${__help_history_index}-1]]
  lappend __help_history [lindex [$text yview] 0]
  incr __help_history_index
  $back configure -state normal
  $forward configure -state disabled

  if {[info exists __help_ref($tag)]} {
    $text yview [set __help_ref($tag)]
  } else {
    error "The tag \"$tag\" does not exist."
  }
}
  
############################################################
# go forward in the "help path" (like netscape)
# return - nothing
############################################################
proc help`forward {} {
  global __help_history __help_history_index __SN
  set back $__SN(help`back)
  set forward $__SN(help`forward)
  set text $__SN(help`text)

  # changeing the current location in the history list
  set index ${__help_history_index}
  set __help_history [concat [lrange ${__help_history} 0 [expr $index-1]]\
		    [lindex [$text yview] 0]\
		    [lrange ${__help_history} [expr $index+1] end]]
  
  incr __help_history_index
  set fraction [lindex ${__help_history} ${__help_history_index}]
  if {${__help_history_index} == [llength ${__help_history}]-1} {
    $forward configure -state disabled
  }
  $back configure -state normal
  $text yview moveto $fraction
}

############################################################
# go back in the "help path" (like netscape)
# return - nothing
############################################################
proc help`back {} {
  global __help_history __help_history_index __SN
  set back $__SN(help`back)
  set forward $__SN(help`forward)
  set text $__SN(help`text)

  # changeing the current location in the history list
  set index ${__help_history_index}
  set __help_history [concat [lrange ${__help_history} 0 [expr $index-1]]\
		    [lindex [$text yview] 0]\
		    [lrange ${__help_history} [expr $index+1] end]]

  incr __help_history_index -1
  set fraction [lindex ${__help_history} ${__help_history_index}]
  if {${__help_history_index} == 0} {
    $back configure -state disabled
  }
  $forward configure -state normal
  $text yview moveto $fraction
}

############################################################
# Setup the help text
# path   - the widget path, which the help applys to
# token  - the token, which identifies the help text
# return - nothing
############################################################
proc help`add {path token} {
  global __help_helpindex
  set __help_helpindex($path) $token
}

############################################################
# Open the help page, and go to the location where token is
# defined
# path   - the path, which help shal be found on
# return - nothing
############################################################
proc help`lookUp {path} {
  global __help_helpindex

  # try to match the name with something in the helpindex
  # until it matches
  for {set i [string length $path]} {$i > 0} {incr i -1} {
    set str [string range $path 0 [expr $i-1]]
    if {[info exists __help_helpindex($str)]} {
      set tag [set __help_helpindex($str)]
      break
    }
  }
  if {$i == 0} {
    error "Lookup couldn't match string \"$path\""
  }

  help`gotoTag $tag
}

############################################################
# This function search for the text typed in the label entry
# direction - forwards or backwards
############################################################
proc __help_search {direction {start ""} } {
  global __help_search __SN __help_history __help_history_index
  set text $__SN(help`text)
  set back $__SN(help`back)
  set forward $__SN(help`forward)

  $text tag delete help_search
  if {${__help_search} == ""} return

  if {$direction == "forwards"} {
    set end end
    set op +
  } else {
    set end 1.0
    set op -
  }

  ### if start is not given we calculate it from the offset in the document.
  ### This is a bit tricky since we cant get the index of the first character
  ### of the page, but only which fraction of the whole document this
  ### character is located. So from the total amount of lines and this
  ### fraction we try to calculate the index. Rounding errors force us
  ### to add 2 lines to this calculated index, to avoid infiniti loop,
  ### due to that it always find the same text
  if {$start == ""} {
    set totalNoOfLines [lindex [$text index end] 0]
    set indexStartOfPage [lindex [$text yview] 0]
    set start [$text index \
		   "[expr int($totalNoOfLines * $indexStartOfPage)].0 $op 2l"]
  }
  set yview [$text yview]
  

  ### color all matches
  set index [$text search -nocase -count count -- ${__help_search} 1.0]
  while {$index  != ""} {
    if {$count == 0} {
      error "The pattern match the empty string" \
	  help_search_empty_string
    }
    set next [$text index $index+${count}c]
    $text tag add help_search $index $next
    set index [$text search -count count -nocase -forwards\
		   -- ${__help_search} $next end]
  }

  ### find the first match from the ofset given
  $text tag configure help_search -foreground white -background black
  
  set first [$text search -$direction -nocase -- \
		 ${__help_search} $start $end]

  if {$first != ""} {
    $text yview $first
  }

  ### test if the view has changed, if not it means that we are at the
  ### bottom of the document
  if {$first != "" && $yview != [$text yview] } {
    # add the element to the history
    set __help_history [lrange ${__help_history} 0 [expr ${__help_history_index}-1]]
    lappend __help_history [lindex [$text yview] 0]
    incr __help_history_index
    $back configure -state normal
    $forward configure -state disabled
    $text yview $first    
  } else {
    if {$direction == "forwards"} {
      set new_start 1.0
      set new_text beginning
    } else {
      set new_start end
      set new_text end
    }
    set answer [tk_dialog .notfound "Text not found" "Text not found. Start from the $new_text ?" questhead 0 Yes No]
    if {$answer == 0} {
      __help_search $direction $new_start
    }
  }
}

######################################################################
### This function add/remove the scrollbar to the index listbox
######################################################################
proc helpResize {} {
  global __SN
  set listbox $__SN(help`listbox)
  set scroll $__SN(help`scroll)
  if {[lindex [$listbox yview] 1] != 1} {
    pack $scroll -fill y  -before $listbox -side left
  } else {
     pack forget $scroll
  }
}

############################################################
#  This takes care of help for the element on the menu
############################################################
proc help {name path} {
  global __editInfo __widgetArgs
  set function $__editInfo(name)
  set help $__widgetArgs(${function}__${name}__help)
  set text $__widgetArgs(${function}__${name}__text)
  setDesc "[subst $text]\n\n$help" $path
}

############################################################
#                   show the about box
############################################################
proc about {} {
  global module __editInfo argv

  set w [makeTempWindow "About"]

	image create photo GeneratorLogo \
      -file [lindex $argv 0]/bitmaps/GeneratorLogo.gif
	label $w.label -image GeneratorLogo

  label $w.1 -text "Author:" -justify left -anchor w 
  label $w.2 -text "Jesper K. Pedersen\nOdense University\nDenmark" \
      -justify left -anchor w 
  label $w.3 -text "Version: $__editInfo(version)" -anchor w 
  label $w.4 -text "Release Date: $__editInfo(releaseDate)" -anchor w 
  label $w.space -anchor w 
  label $w.5 -text "The $module(name) module" -anchor w 
  label $w.6 -text "Creator:" -anchor w 
  label $w.7 -text $module(creator) -justify left -anchor w 
  label $w.8 -text "Version: $module(version)" -anchor w 
  button $w.ok -text OK -command "destroy $w"
  
  pack $w.label -pady 5
  pack $w.1 -padx 20 -fill x -expand 1 -anchor w
  pack $w.2 -padx 40 -fill x -expand 1 -anchor w
  pack $w.3 -padx 20 -fill x -expand 1 -anchor w
  pack $w.4 -padx 20 -fill x -expand 1 -anchor w
  pack $w.space -pady 5 -fill x -expand 1 -anchor w
  pack $w.5 -padx 20 -fill x -expand 1 -anchor w
  pack $w.6 -padx 20 -fill x -expand 1 -anchor w
  pack $w.7 -padx 40 -fill x -expand 1 -anchor w
  pack $w.8 -padx 20 -fill x -expand 1 -anchor w

  pack $w.ok  -anchor e
}
############################################################
#         This function takes care of help for
#         element's in listbox's
############################################################
proc listbox_help {path name y helpPath} {

  global __widgetArgs __editInfo
  set function $__editInfo(name)
  set index [$path.box nearest $y]
  set entries $__widgetArgs(${function}__${name}__entries)
  set entryhelp $__widgetArgs(${function}__${name}__entryhelp)
  set help [lindex $entryhelp [expr 2*$index+1]]
  if {$help == ""} {
    set help $__widgetArgs(${function}__${name}__help)
    set text $__widgetArgs(${function}__${name}__text)
  } else {
    set text [lindex $entries $index ]
  }

  if {$helpPath != $path} {
    ### The element is a ComboBox

    ### calculate the geometry of the windows
    set topGeometry [winfo geometry [winfo toplevel $helpPath]]
    set descGeometry \
        [winfo geometry [winfo toplevel $helpPath].description]
    set comboGeometry [wm geometry [winfo toplevel $path]]

    ### read the geometry
    if {![regexp {^([0-9]+)x([0-9]+)([+-][0-9]+)([+-][0-9]+)$} $topGeometry \
              all topDx topDy topSx topSy]} {
      error "Internal error: couldn't match regexp geometry: $topGeometry"
    }
    if {![regexp {^([0-9]+)x([0-9]+)([+-][0-9]+)([+-][0-9]+)$} $descGeometry \
              all descDx descDy descSx descSy]} {
      error "Internal error: couldn't match regexp geometry: $descGeometry"
    }
    if {![regexp {^([0-9]+)x([0-9]+)([+-][0-9]+)([+-][0-9]+)$} $comboGeometry \
              all comboDx comboDy comboSx comboSy]} {
      error "Internal error: couldn't match regexp geometry: $comboGeometry"
    }

    ### calculate the geometry of the desc window
    set startX [expr $descSx + $topSx]
    set startY [expr $descSy + $topSy]
    set endX [expr $startX + $descDx]
    set endY [expr $startY + $descDy]

    set comboEndX [expr $comboSx + $comboDx]
    set comboEndY [expr $comboSy + $comboDy]

    ### is the combo window overlapping?
    ### please refer to le-buk
    if {$endX > $comboSx && $startX < $comboEndX &&
        $endY > $comboSy && $startY < $comboEndY} {
      set w [makeTempWindow Help]
      pack [label $w.label -text "$text\n\n$help" -wraplength 500 -justify left]
      pack [button $w.ok -text "OK" -command "destroy $w"]
      wm withdraw $w
      update idletasks
      set x [expr [winfo screenwidth $w]/2 - [winfo reqwidth $w]/2 \
                 - [winfo vrootx [winfo parent $w]]]
      set y [expr [winfo screenheight $w]/2 - [winfo reqheight $w]/2 \
                 - [winfo vrooty [winfo parent $w]]]
      wm geom $w +$x+$y
      wm deiconify $w
      update
      set binding [bind all <1>]
      bind all <1> {}
      pushGrab global $w
      tkwait window $w
      popGrab
      bind all <1> $binding
      return
    }
  }
  setDesc "$text\n\n$help" $helpPath
}

############################################################
#         This function takes care of help for
#         element's in menu's and radio's
############################################################
proc menu_help {name index path} {
  global __widgetArgs __editInfo
  set function $__editInfo(name)
  set entries $__widgetArgs(${function}__${name}__entries)
  set entryhelp $__widgetArgs(${function}__${name}__entryhelp)
  set help  [lindex $entryhelp [expr 2*$index+1]]
  if {$help == ""} {
    set help $__widgetArgs(${function}__${name}__help)
    set text $__widgetArgs(${function}__${name}__text)
  } else {
    set text [lindex $entries $index ]
  }
  setDesc "$text\n\n$help" $path
}

proc showFile {file} {
  global argv
  set w [makeTempWindow ""]
  button $w.ok -text "OK" -command "catch {destroy $w}"
  pack $w.ok -side bottom

  text $w.mesg -yscrollcommand "$w.scroll set"
  scrollbar $w.scroll -command "$w.mesg yview"
  pack $w.mesg $w.scroll -side left -fill y
  set FILE [open [lindex $argv 0]/$file]
  while {![eof $FILE]} {
    gets $FILE line
    $w.mesg insert end "$line\n"
  }
  $w.mesg configure -state disabled
}

proc startBrowser {url} {
  global __system __startingBrowser
  if {[info exists __startingBrowser]} return

  set w [toplevel .browser]
  wm transient .browser

  if {$__system(browser) == ""} {
    label .browser.label -text \
      "\nNo WWW browser installed\n"
  } else {
    label .browser.label -text \
      "\nStarting external WWW browser: $__system(browser)\nplease wait....\n"
    eval "exec $__system(browser) $url > /dev/null  &"
  }
  pack .browser.label

  after 5000 "catch \"destroy .browser\";catch \"unset __startingBrowser\""
  set __startingBrowser 1

  wm withdraw $w
  update idletasks
  set x [expr [winfo screenwidth $w]/2 - [winfo reqwidth $w]/2 \
	     - [winfo vrootx [winfo parent $w]]]
  set y [expr [winfo screenheight $w]/2 - [winfo reqheight $w]/2 \
	     - [winfo vrooty [winfo parent $w]]]
  wm geom $w +$x+$y
  wm deiconify $w

}
