//=====================================================================
// File:    LinearCutoff.java
// Class:   LinearCutoff
// 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.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

/**
 * This cutoff function represents a horizontal line. It is set at a
 * specific value, determined by the first (and only) option set. This
 * means that the cutoff hieght is independent of the size. The
 * cutoff functions are used to help score bins and can also be used by
 * peak locating algorithms.
 *
 * @see CutoffFunction
 *
 * @author James J. Benham
 * @version 1.0.0
 * @date August 10, 1998
 */

public class LinearCutoff extends CutoffFunction
{
  double value;

  /**
   * Creates a new linear function with the value specified in value.
   *
   * @param value   the number to return as the cutoff
   */
  public LinearCutoff()
  {
    name = "Linear";
    descript = "Sets a constant cutoff point for a region in the lane.";
    helpFile = "linear.html";

    value = -1;

    // Mark options as unset
    options = null;
  }

  /**
   * Gives the name of this linear function.
   *
   * @return  the name for this type of function.
   */
  public String getName()
  {
    return name;
  }

  /**
   * Gives a brief description of the linear filter.
   *
   * @return  a sentence describing the function.
   */
  public String getDescription()
  {
    return descript;
  }

  /**
   * Gives help for the linear cutoff.
   *
   * @return a html or plaintext file with the description. <code>null</code>
   * if this file does not exist.
   */
  public String getHelpFile()
  {
    return helpFile;
  }

  /**
   * Returns the options/parameters for this Cutoff function. In this case,
   * the value to cut off at is required.
   *
   * @return an option representing the value to cut off at.
   */
  public Option[] getOptions()
  {
    Option[] opts = new Option[1];
    opts[0] = new Option("Value", Option.NUMBER, true, 0);

    return opts;
  }

  /**
   * Set the value for the cutoff. This must be done before the funtion
   * can work.
   *
   * @param the option with the value for the cutoff.
   *
   * @exception MissingParameterError the value was not provided in
   *    the <code>opts</code> parameter.
   */
  public void setOptions(Option[] opts)
  {
    // check the input
    if(opts == null)
      throw new MissingParameterError("Value not provided to linear cutoff.");

    // could check to see that getNumValue didn't give -1.

    options = opts;
    value = opts[0].getNumValue();
  }

  /**
   * Gives the cutoff point for this function. Since it is linear, it is
   * independent of the position.
   *
   * @param position  this parameter is ignored in this case
   *
   * @exception MissingParameterError occurs if the value for this cutoff
   *    function has not been set.
   */
  public double getCutoff(double position)
  {
    // see if the value has been set
    if((options == null) || (value == -1))
      throw new MissingParameterError("No value set for linear cutoff.");
      
    return value;
  }

  /**
   * Writes all of the information this class needs to store in order
   * to be recreated. This will be used for things like storing the
   * class in a file. Therefore, the write should output enough information
   * so that <code>read</code> can recreate the essential properties of this
   * class.
   *
   * @param out  the destination to write the data to.
   *
   * @exception IOException  occurs when a problem is encountered when
   *     writing to the stream.
   */
  public void write(DataOutputStream out) throws IOException
  {
    out.writeDouble(value);
  }

  /**
   * Reads in the properties of this class from the specified input stream.
   * The stream data should have been created by <code>write</code>. This
   * will retrieve this classes state from the input stream. All of the
   * current data in this class will be replaced by the data from the 
   * stream.
   *
   * @param in  the input stream with the data for the class.
   *
   * @exception IOException  occurs when a problem is encountered when
   *     writing to the stream.
   */
  public void read(DataInputStream in) throws IOException
  {
    value = in.readDouble();
    // set the option's so it points to the right thing, otherwise the
    // class will think nothing has been set
    options = new Option[1];
    options[0] = new Option("Value", Option.NUMBER, true, 0);
    options[0].setValue(value);
  }
}
