//=====================================================================
// File:    ProgOptions.java
// Class:   ProgOptions
// Package: AFLPcore
//
// Author:  James J. Benham
// Date:    August 10, 1998
// Contact: james_benham@hmc.edu
//
// Genographer v1.0 - Computer assisted scoring of gels.
// Copyright (C) 1998  Montana State University
// 
// This program 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; version 2
// of the License.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// The GNU General Public License is distributed in the file GPL
//=====================================================================

package AFLPcore;

import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;

/**
 * This class contains static methods and variables that provide 
 * several features to the program. It controls most of the options that
 * the porgram needs. It contains the path that the program is in as well
 * as the browser that displays the help files. It contains methods to
 * run the help browser as well as a method to parse the configuration file.
 *
 * @author James J. Benham
 * @version 1.0.0
 * @date August 10, 1998
 */

public class ProgOptions
{
  private static final String HELP_PATH = "doc" + File.separator;
  private static final String CONFIG_FILE = "genograph.cfg";

  /**
   * This is the path that points to the program directory. It's used
   * so other parts of the program can know where to find things, like
   * standard definition files, images, or help files.
   */
  public static String homePath;

  private static String browser;

  private static String optNames[];

  private static String optValues[];

  /**
   * This displays the specified helpfile in a web browser. The
   * browser is defined in the file "genograph.cfg" 
   *
   * @param helpFile   the file name of the help file. It is assumed
   *                   that the file is in the "doc" subdirectory.
   *
   * @exception IOException  occurs if the browser file or help file
   *                         contain an error
   * @excpetion NoBrowserException  occurs if the browser is not
   *           set in the configuration file.
   */
  public static void showHelp(String helpFile) throws IOException
  {
    String fullName = homePath + HELP_PATH + helpFile;
    // change it into a file to and then back to let java resolve all
    // of the system dependent crap.
    File help = new File(fullName);
    fullName = help.toString();

    // Check for errors.
    File browserFile = new File(browser);

    if(browser.equals(""))
      throw new NoBrowserException("Browser not set! See the file " +
				   homePath + HELP_PATH + "help.html");

    // This seems to be false even when the file really does exist.
    // I don't know why it doesn't works. Still, this would be a nice check
    // to do. Maybe it's being case sensitive or something, but I don't
    // know the correct case for win95, since it's case insensitive.
    //    if(!browserFile.exists())
    //      throw new NoBrowserException("Browser not found! See the file " +
    //				   homePath + HELP_PATH + "help.html");

    // Start the browser
    Runtime.getRuntime().exec(browser + " " + fullName);
  }

  /**
   * Reads in the options form the configuration file. Make sure that this
   * is called before trying to use program options.
   */
  public static void readOptions()
  {
    optNames = new String[2];
    optNames[0] = "BROWSER";
    optNames[1] = "BASE_MIN";

    optValues = new String[2];

    // Create an input reader
    try{
      BufferedReader in = new BufferedReader(new FileReader(homePath +
							    CONFIG_FILE));
      String line = nextLine(in);
      String name;
      String value;
      int spaceIndex;
      while(line != null)
	{
	  // get the value
	  spaceIndex = line.indexOf(" ");
	  name = line.substring(0, spaceIndex);
	  value = line.substring(spaceIndex, line.length());

	  // See if it matches a name. If it does, store it.
	  for(int i=0; i < optNames.length; i++)
	    if(name.equals(optNames[i]))
	      {
		optValues[i] = value;
		break;
	      }
	  
	  // Store the browser in a special variable.
	  browser = optValues[0];

	  line = nextLine(in);
	}
    } catch(IOException e) {
      System.err.println("Unable to read config file. See help."
			 +" Using defaults");
      browser = "";
    }
  }

  /**
   * Gives the value of a parameter specified in the input file.
   *
   * @param param  the name of the parameter to retrieve, ie BROWSER
   *
   * @return the text on the line immediately following the name. It
   *         will be <code>null</code> if the parameter was not specified.
   */
  public static String retrieve(String param)
  {
    String value;

    for(int i=0; i < optNames.length; i++)
      if(param.equals(optNames[i]))
	return optValues[i];

    return null;
  }

  /**
   * Gets a line from the specified input stream. It will skip over blank
   * lines and lines beginning with a '#'. Additionally, white space will
   * be trimmed from both ends of the string.
   *
   * @param inStream  the stream to read from
   *
   * @return the line that isn't blank or a comment. <code>null</code>
   * will be returned if the end of the stream is reached.
   *
   * @exception IOException if an I/O problem occurs.
   */
  public static String nextLine(BufferedReader inStream) throws IOException
  {
    char firstCh = 'a';
    String line;

    do
      {
	line = inStream.readLine();
	if(line != null)
	  {
	    line.trim();
	    if(line.length() >= 1)
	      firstCh = line.charAt(0);
	  }
	// repeat if not the end and the line is blank or a comment
      } while( (line != null) && ((line.length() == 0) || (firstCh == '#')));

    return line;
  }
}
