Index: /trunk/gli/src/org/greenstone/gatherer/gui/HelpFrame.java
===================================================================
--- /trunk/gli/src/org/greenstone/gatherer/gui/HelpFrame.java	(revision 10646)
+++ /trunk/gli/src/org/greenstone/gatherer/gui/HelpFrame.java	(revision 10647)
@@ -53,4 +53,5 @@
 import org.w3c.dom.*;
 
+
 /**
  * This class provides a nice help facility. It is a separate frame that can be positioned
@@ -59,7 +60,6 @@
  */
 public class HelpFrame 
-    extends JFrame {
-
-    static private final String NULL_STRING = "<null>";
+    extends JFrame
+{
     /** The size of the frame */
     static private final Dimension SIZE = new Dimension(760, 560);
@@ -67,12 +67,12 @@
     static private HelpFrame self = null;
 
-    /** The HTML rendering pane */
-    private JEditorPane view = null;
-    /** The contents tree model */
-    private ContentsModel model = null;
-    /** A contents tree for the top of the frame */
-    private JTree contents = null;
-
-    private JSplitPane split_pane = null;
+    /** The help view at the bottom of the frame. */
+    static private JEditorPane help_pane = null;
+    /** The help contents tree at the top of the frame. */
+    static private JTree help_contents_tree = null;
+    /** The help contents tree model. */
+    static private HelpContentsTreeModel help_contents_tree_model = null;
+    /** The split between the contents tree and the page view. */
+    static private JSplitPane split_pane = null;
 
 
@@ -83,23 +83,23 @@
 	Dictionary.registerText(this, "Help.Title");
 
-	view = new JEditorPane();
-	view.setEditable(false);
-	view.addHyperlinkListener(new ViewHyperlinkListener());
-
-	HelpItem rootNode = new HelpItem(Dictionary.get("Help.Contents"), NULL_STRING);
-	model = new ContentsModel(rootNode);
-	contents = new JTree((DefaultTreeModel) model);
-	contents.addTreeSelectionListener(new ContentsListener());
-	contents.setExpandsSelectedPaths(true);
+	help_pane = new JEditorPane();
+	help_pane.setEditable(false);
+	help_pane.addHyperlinkListener(new HelpPaneHyperlinkListener());
+
+	HelpContentsTreeNode help_tree_root_node = new HelpContentsTreeNode(null, Dictionary.get("Help.Contents"));
+	help_contents_tree_model = new HelpContentsTreeModel(help_tree_root_node);
+	help_contents_tree = new JTree((DefaultTreeModel) help_contents_tree_model);
+	help_contents_tree.addTreeSelectionListener(new HelpContentsTreeSelectionListener());
+	help_contents_tree.setExpandsSelectedPaths(true);
 
 	// Creation
 	JPanel content_pane = (JPanel) this.getContentPane();
 	split_pane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
-	JScrollPane index_scroll = new JScrollPane(contents);
-	JScrollPane view_scroll = new JScrollPane(view);
+	JScrollPane help_contents_tree_scroll = new JScrollPane(help_contents_tree);
+	JScrollPane help_pane_scroll = new JScrollPane(help_pane);
 
 	// Layout
-	split_pane.add(index_scroll, JSplitPane.LEFT);
-	split_pane.add(view_scroll, JSplitPane.RIGHT);
+	split_pane.add(help_contents_tree_scroll, JSplitPane.LEFT);
+	split_pane.add(help_pane_scroll, JSplitPane.RIGHT);
 	content_pane.setLayout(new BorderLayout());
 	content_pane.add(split_pane, BorderLayout.CENTER);
@@ -118,25 +118,21 @@
     public void destroy()
     {
-	view = null;
-	contents = null;
-    }
-
-
-    /** Retrieve the full file path to the help index xml file.
-     * @return the full path as a String
-     */
+	help_contents_tree = null;
+	help_pane = null;
+    }
+
+
+    /** Retrieve the relative file path to the language-specific help index xml file. */
     private String getHelpFolder()
     {
 	String help_folder = "help/" + Configuration.getLanguage() + "/";
 
-	// Try in the JAR/classes directory first
-	URL help_folder_url = JarTools.getResource("/" + help_folder);
-	if (help_folder_url != null) {
+	// Applet case: get help files out of JAR file
+	if (Gatherer.isApplet && JarTools.getResource("/" + help_folder) != null) {
 	    return help_folder;
 	}
 
-	// Look in the base directory next
-	File help_folder_file = new File(help_folder);
-	if (help_folder_file.exists()) {
+	// Normal case: get help files out of GLI "help" folder
+	if (new File(help_folder).exists()) {
 	    return help_folder;
 	}
@@ -147,25 +143,67 @@
 
 
+    private URL getURLForSection(String section_name)
+    {
+	// Form the path to the help file from the section name
+	if (section_name != null) {
+	    String help_file_path = getHelpFolder() + section_name + StaticStrings.HTM_FILE_EXTENSION;
+
+	    try {
+		// Applet case: get help file out of JAR file
+		if (Gatherer.isApplet) {
+		    return JarTools.getResource("/" + help_file_path);
+		}
+
+		// Normal case: get help file out of GLI "help" folder
+		return (new File(help_file_path)).toURL();
+	    }
+	    catch (Exception exception) {
+		DebugStream.printStackTrace(exception);
+	    }
+	}
+
+	return null;
+    }
+
+
+    static private void selectHelpContentsTreeNode(String section_name)
+    {
+	// Find the tree node with this section name, then select it
+	selectHelpContentsTreeNode(help_contents_tree_model.getHelpContentsTreeNodeNamed(section_name));
+    }
+
+
+    static private void selectHelpContentsTreeNode(HelpContentsTreeNode help_tree_node)
+    {
+	// Ensure the node in the help contents tree is selected and visible
+	TreePath help_tree_node_path = new TreePath(help_tree_node.getPath());
+	help_contents_tree.setSelectionPath(help_tree_node_path);
+	help_contents_tree.scrollPathToVisible(help_tree_node_path);
+    }
+
+
     static public void setView(String section_name)
     {
-	self.setViewInternal(section_name);
-    }
-
-
-    public void setViewInternal(String sectionName)
-    {
-	// Find the node in the tree with the specified sectionName
-	HelpItem node = model.getHelpItemNamed(sectionName);
-
-	// Ensure the node is selected and visible
-	TreePath path = new TreePath(node.getPath());
-	contents.setSelectionPath(path);
-	contents.scrollPathToVisible(path);
-
+	// Select the appropriate node in the help contents tree
+	selectHelpContentsTreeNode(section_name);
+
+	// Show the help page with the specified section name
+	self.showHelpPage(section_name);
+    }
+
+
+    private void showHelpPage(String section_name)
+    {
+	// Find the tree node with this section name, then show the page for the node
+	showHelpPage(getURLForSection(section_name));
+    }
+
+
+    private void showHelpPage(URL help_page_url)
+    {
 	// Display the selected page
-	URL url = node.getURL();
-	if (url != null) {
+	if (help_page_url != null) {
 	    try {
-		view.setPage(url);
+		help_pane.setPage(help_page_url);
 	    }
 	    catch (Exception exception) {
@@ -180,48 +218,50 @@
 
 
-    private class ContentsModel
-	extends DefaultTreeModel {
-
-	public ContentsModel(MutableTreeNode rootNode) {
-	    super(rootNode);
-
-	    // Load the XML help file and build the contents structure from it
+    private class HelpContentsTreeModel
+	extends DefaultTreeModel
+    {
+	public HelpContentsTreeModel(MutableTreeNode help_tree_root_node)
+	{
+	    super(help_tree_root_node);
+
+	    // Load the XML help index file and build the contents structure from it
 	    try {
-		String help_index = getHelpFolder() + StaticStrings.HELP_INDEX_FILENAME;
-		Document document = XMLTools.parseXMLFile(help_index, true);
-
-		// Traverse the document hierarchy, building a tree representing its structure
-		Node documentNode = document.getFirstChild();
-
-		int sectionNum = 0;
-		NodeList children = documentNode.getChildNodes();
+		String help_index_file_path = getHelpFolder() + "help_index.xml";
+		Document document = XMLTools.parseXMLFile(help_index_file_path, true);
+
+		// Traverse the help hierarchy, building a tree representing its structure
+		Node document_node = document.getFirstChild();
+
+		// Add a help contents tree node for each major section
+		int section_number = 0;
+		NodeList children = document_node.getChildNodes();
 		for (int i = 0; i < children.getLength(); i++) {
 		    Node child = children.item(i);
 		    if (child.getNodeName().equals(StaticStrings.SECTION_ELEMENT)) {
-			sectionNum++;
-			buildContentsHierarchy(rootNode, sectionNum + StaticStrings.EMPTY_STR, child);
+			section_number++;
+			buildHelpContentsTree(help_tree_root_node, section_number + StaticStrings.EMPTY_STR, child);
 		    }
 		}
 	    }
-	    catch (Exception ex) {
-		ex.printStackTrace();
-	    }
-	}
-
-
-	public void buildContentsHierarchy(MutableTreeNode parent, String pos, Node node)
+	    catch (Exception exception) {
+		DebugStream.printStackTrace(exception);
+	    }
+	}
+
+
+	private void buildHelpContentsTree(MutableTreeNode parent, String pos, Node node)
 	{
 	    // Determine the section name
-	    String sectionName = ((Element) node).getAttribute(StaticStrings.NAME_ATTRIBUTE);
+	    String section_name = ((Element) node).getAttribute(StaticStrings.NAME_ATTRIBUTE);
 
 	    // Determine the section title
-	    String sectionTitle = "";
+	    String section_title = "";
 	    NodeList children = node.getChildNodes();
 	    for (int i = 0; i < children.getLength(); i++) {
 		Node child = children.item(i);
 		if (child.getNodeName().equals(StaticStrings.TITLE_ELEMENT)) {
-		    sectionTitle = pos + ": ";
+		    section_title = pos + ": ";
 		    if (child.getFirstChild() != null) {
-			sectionTitle = sectionTitle + child.getFirstChild().getNodeValue();
+			section_title += child.getFirstChild().getNodeValue();
 		    }
 		}
@@ -229,32 +269,34 @@
 
 	    // Add the node into the tree
-	    HelpItem item = new HelpItem(sectionTitle, sectionName);
-	    insertNodeInto(item, parent, parent.getChildCount());
+	    HelpContentsTreeNode help_tree_node = new HelpContentsTreeNode(section_name, section_title);
+	    insertNodeInto(help_tree_node, parent, parent.getChildCount());
 
 	    // Apply recursively to the children of this node
-	    int sectionNum = 0;
+	    int section_number = 0;
 	    for (int i = 0; i < children.getLength(); i++) {
 		Node child = children.item(i);
 		if (child.getNodeName().equals(StaticStrings.SECTION_ELEMENT)) {
-		    sectionNum++;
-		    buildContentsHierarchy(item, pos + StaticStrings.STOP_CHARACTER + sectionNum, child);
-		}
-	    }
-	}
-
-
-	public HelpItem getHelpItemNamed(String sectionName)
-	{
-	    // Find the node with name matching sectionName, somewhere in the tree
-	    Enumeration descendants = ((DefaultMutableTreeNode) root).preorderEnumeration();
-	    while (descendants.hasMoreElements()) {
-		HelpItem node = (HelpItem) descendants.nextElement();
-		if (node.name.equals(sectionName)) {
-		    return node;
+		    section_number++;
+		    buildHelpContentsTree(help_tree_node, pos + StaticStrings.STOP_CHARACTER + section_number, child);
+		}
+	    }
+	}
+
+
+	private HelpContentsTreeNode getHelpContentsTreeNodeNamed(String section_name)
+	{
+	    // Find the node with name matching section name, somewhere in the tree
+	    if (section_name != null) {
+		Enumeration descendants = ((DefaultMutableTreeNode) root).preorderEnumeration();
+		while (descendants.hasMoreElements()) {
+		    HelpContentsTreeNode help_tree_node = (HelpContentsTreeNode) descendants.nextElement();
+		    if (section_name.equals(help_tree_node.section_name)) {
+			return help_tree_node;
+		    }
 		}
 	    }
 
 	    // Couldn't be found, so just return the root (Contents) node
-	    return (HelpItem) root;
+	    return (HelpContentsTreeNode) root;
 	}
     }
@@ -264,7 +306,7 @@
      * to show the appropriate page as required.
      */
-    private class ContentsListener
-	implements TreeSelectionListener {
-
+    private class HelpContentsTreeSelectionListener
+	implements TreeSelectionListener
+    {
 	/** Any implementation of <i>TreeSelectionListener</i> must include this method so we can be informed when the tree selection changes.
 	 * @param event A <strong>TreeSelectionEvent</strong> containing al the relevant information about the event itself.
@@ -272,15 +314,7 @@
 	public void valueChanged(TreeSelectionEvent event)
 	{
-	    TreePath path = event.getPath();
-	    HelpItem node = (HelpItem) path.getLastPathComponent();
-	    URL url = node.getURL();
-	    if (url != null) {
-		try {
-		    view.setPage(url);
-		}
-		catch (Exception exception) {
-		    DebugStream.printStackTrace(exception);
-		}
-	    }
+	    HelpContentsTreeNode help_tree_node = (HelpContentsTreeNode) event.getPath().getLastPathComponent();
+	    selectHelpContentsTreeNode(help_tree_node);
+	    showHelpPage(help_tree_node.section_name);
 	}
     }
@@ -290,66 +324,41 @@
      * provides the ability to set an html page to be loaded when this node is selected.
      */
-    private class HelpItem 
-	extends DefaultMutableTreeNode {
-
+    private class HelpContentsTreeNode 
+	extends DefaultMutableTreeNode
+    {
 	/** The unique name of the section (matches the HTML filename) */
-	public String name = null;
+	public String section_name = null;
 	/** The title to be displayed for this tree node. */
-	public String title = null;
-
-
-	/** Constructor.
-	 * @param title The title to be shown for this node as a <strong>String</strong>.
-	 * @param name The name of the section as a <strong>String</strong>.
-	 */
-	public HelpItem(String title, String name)
-	{
-	    this.name = name;
-	    this.title = title;
-	}
-
-
-	/** Method to create a url from the file name.
-	 * @return A <strong>URL</strong> that points to the file's location.
-	 */
-	public URL getURL()
-	{
-	    URL url = null;
-
-	    if (name != null && !name.equals("") && !name.equals(NULL_STRING)) {
-		String help_file_path = getHelpFolder() + name + StaticStrings.HTM_FILE_EXTENSION;
-		File help_file = new File(Gatherer.getGLIDirectoryPath() + help_file_path);
-		if (Gatherer.isGsdlRemote) {
-		    help_file = new File(Gatherer.getGLIUserDirectoryPath() + help_file_path);
-		}
-		try {
-		    url = help_file.toURL();
-		}
-		catch (Exception exception) {
-		    DebugStream.printStackTrace(exception);
-		}
-	    }
-
-	    return url;
-	}
-
+	public String section_title = null;
+
+	public HelpContentsTreeNode(String section_name, String section_title)
+	{
+	    this.section_name = section_name;
+	    this.section_title = section_title;
+	}
 
 	public String toString()
 	{
-	    return title;
-	}
-    }
-
-
-    private class ViewHyperlinkListener
-	implements HyperlinkListener {
-	public void hyperlinkUpdate(HyperlinkEvent e) {
-	    if(e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
-		try {
-		    view.setPage(e.getURL());
-		}
-		catch(Exception exception) {
-		    DebugStream.printStackTrace(exception);
-		}
+	    return section_title;
+	}
+    }
+
+
+    private class HelpPaneHyperlinkListener
+	implements HyperlinkListener
+    {
+	public void hyperlinkUpdate(HyperlinkEvent e)
+	{
+	    if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
+		// Determine which node in the help contents tree to select, then select it
+		String section_link = e.getURL().getFile();
+		if (section_link.endsWith(".htm")) {
+		    section_link = section_link.substring(section_link.lastIndexOf("/") + 1);
+		    section_link = section_link.substring(0, section_link.length() - ".htm".length());
+		    selectHelpContentsTreeNode(section_link);
+		}
+
+		// Change to the page specified by the link
+		showHelpPage(e.getURL());
 	    }
 	}
