//=====================================================================
// File:    Peak.java
// Class:   Peak
// 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 class represents a peak. A peak is a point of interest in a lane,
 * which theoretically should represent a fragement of a given size.
 * Peaks are used by the <code>ScoreFunction</code> to determine how to
 * score a lane. The peaks can be choosen by a class that extends
 * <code>PeakLocate</code>. The lane will contain a list of peaks.
 *
 * @see PeakLocate
 * @see Lane
 * @see ScoreFunction
 *
 * @author James J. Benham
 * @version 1.0.0
 * @date August 10, 1998
 */

public class Peak extends SortableData
{
  private double location;
  private double height;
  private double area;
  private double confidence;
  private boolean marked;
  
  /**
   * Creates a new peak with the specified parameters. The confidence of
   * this peak is set to 1 by default. Also, by default the peak is not
   * marked.
   *
   * @param location   the size in bp of the center (top) of the peak
   * @param height     the intensity of the trace at the peak location
   * @param area       the area of the peak.
   */
  public Peak(double location, double height, double area)
  {
    this.location = location;
    this.height = height;
    this.area = area;
    confidence = 1;
    marked = false;
  }

  /**
   * This gives the location of the peek, and is used when searching or
   * sorting objects of this type.
   *
   * @return a value that provides a logical way to sort this object
   */
  public final double getSearchKey()
  {
    return location;
  }

  /**
   * Gives the location of the peek in the data.
   *
   * @return the position in bp
   */
  public final double getLocation()
  {
    return location;
  }

  /**
   * Gives the height of the peak.
   *
   * @return the height
   */
  public final double getHeight()
  {
    return height;
  }

  /**
   * Gives the area of this peek. The actual calculation of the area is
   * handled outside of this class.
   *
   * @return  the area
   */
  public final double getArea()
  {
    return area;
  }

  /**
   * Changes this peak so that the location, height, and size are set
   * to the values given. Remember that changing the location will also
   * change the height and area.
   *
   * @param location  the position in the trace, in bp.
   * @param height    the height of the peak
   * @param area      the area of the peak
   */
  public void set(double location, double height, double area)
  {
    this.location = location;
    this.height = height;
    this.area = area;
  }

  /**
   * Gives the confidence associated with this peak. The confidence is a
   * measure of how sure the program is that this peak is actually a
   * peak. It should be set by whatever algorithm is used to select the
   * peak.
   *
   * @return a measure of the certainty that this is a peak, between 0 and 1.0
   */
  public final double getConfidence()
  {
    return confidence;
  }

  /**
   * Sets the confidence to the specified value. This value should be between
   * 0.0 and 1.0. See <code>getConfidence</code> for a description of 
   * confidence.
   *
   * @param confidence  the value to set the confidence to
   *
   * @see Peak#getConfidence
   */
  public final void setConfidence(double confidence)
  {
    this.confidence = confidence;
  }

  /**
   * Tells whether or not this peak is marked. This could be used to
   * include/exclude a peak from analysis. It could also determine if
   * the peak is drawn with a label/indicator of some kind.
   *
   * @return the state of the peak
   */
  public boolean isMarked()
  {
    return marked;
  }

  /**
   * Sets the peak as specified. Marking could be used to indicate which
   * peak will be used in analysis.
   *
   * @param state  the value for the marked state of this peak.
   */
  public void setMarkedState(boolean state)
  {
    marked = state;
  }

  /**
   * Clones this peak <b>Not implemented</b>
   */
  public Object clone()
  {
    System.err.println("Peak clone not implemented.");
    return this;
  }

  /**
   * 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 info in this class will be replaced with data from the 
   * stream.
   *
   * @param in  the input stream with the data for the class.
   *
   * @exception IOException  occurs when a problem is encountered when
   *     reading from the stream.
   */
  public void read(DataInputStream in) throws IOException
  {
    location = in.readDouble();
    height = in.readDouble();
    area = in.readDouble();
    confidence = in.readDouble();
    marked = in.readBoolean();
  }

  /**
   * 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(location);
    out.writeDouble(height);
    out.writeDouble(area);
    out.writeDouble(confidence);
    out.writeBoolean(marked);
  }

}
