//=====================================================================
// File:    ScatterGraph.java
// Class:   ScatterGraph
// Package: AFLPgui
//
// Author:  James J. Benham
// Date:    August 12, 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 AFLPgui;

import java.awt.Color;
import java.awt.Graphics;
import AFLPcore.DataList;
import AFLPcore.Lane;
import AFLPcore.Peak;

/**
 * This class provides a way to draw a graph on a graphics object. This
 * makes it easy for different graphs to be drawn. This one will show
 * the distribution of peak heights. For every lane, the heighest peak's
 * value will be plotted. All of the lanes will be plotted at the same
 * horizontal position. If a lane has more than one peak, a different color
 * will be used, as opposed to those lanes which have only one peak in
 * the specified region. The region is a range of sizes, in bp, which
 * is specified when the graph is drawn.
 *
 * @see Graph
 *
 * @author James J. Benham
 * @version 1.0.0
 * @date August 12, 1998
 */

public class ScatterGraph extends Graph
{
  private static int MARK_WIDTH = 4;
  private static int MARK_HEIGHT = 4;

  private Color singlePeak;
  private Color multiPeak;

  /**
   * Creates a new graph where those lanes with one peak in the defined
   * region will be black and those with more than one peak will be red.
   */
  public ScatterGraph()
  {
    this(Color.black, Color.red);
  }

  /**
   * Creates a new graph with the specified parameters.
   *
   * @param singlePeak  the color for a lane that has only one peak in
   *                    the region.
   * @param multiPeak   the color for a lane that has multiple peaks.
   */
  public ScatterGraph(Color singlePeak, Color multiPeak)
  {
    this.singlePeak = singlePeak;
    this.multiPeak = multiPeak;
  }

 /**
   * Draw the scatter graph with the specified properties.
   *
   * @param g     the graphics to draw on
   * @param x     the x coordinate of the upper left corner of the graph
   *              area. (The position of the vertical axis)
   * @param y     the y coordinate of the upper left corner of the graph
   * @param width the width of the graph area.
   * @param height the height of the graph
   * @param scale  the scale of the graph, pixel = intensity*scale
   * @param minSize  the minimum size, in bp, that the graph should include
   * @param maxSize  the maximum size, in bp, that the graph should include
   * @param lanes  the lanes to include in the graph.
   */
  public void drawGraph(Graphics g, int x, int y, int width, 
                     int height, int bottom_border,
                     double scale, double minSize, double maxSize,
                     DataList lanes)
  {
    int numLanes = lanes.size();

    int x_loc = x + width/2;
    int half_height = MARK_HEIGHT/2;

    Lane ln;
    DataList peaks;
    double intensity;
    for(int i=0; i < numLanes; i++)
      {
     ln = (Lane) lanes.dataAt(i);
     peaks = ln.getPeaksInRange(minSize, maxSize);
     if(!peaks.isEmpty())
       {
         // get the colors and location
         if(peaks.size() == 1)
           {
          intensity = ((Peak) peaks.dataAt(0)).getHeight();
          g.setColor(singlePeak);
           }
         else
           {
          intensity = findMax(peaks);
          g.setColor(multiPeak);
           }

         // draw the actuall marks
         g.fillRect(x_loc, 
                 y + height - (int)(scale*intensity) - half_height,
                 MARK_WIDTH, MARK_HEIGHT);
       }
      }
  }

  /**
   * Gives the preferred width of this graph. Since the scatter graphs
   * width is independent of the number of lanes, this is useful since
   * the graph does not need to be very wide
   *
   * @return gives a value of 20 pixels.
   */
  public int getPreferredWidth()
  {
    return 20;
  }

  /**
   * Gives the maximum height for all of the peaks in the given list. 
   *
   * @param peakList  the peaks to find the maximum height in.
   *
   * @return the largest height value contained by any peak
   */
  protected double findMax(DataList peakList)
  {
    double max = 0;
    double temp;

    for(int i=0; i < peakList.size(); i++)
      {
     temp = ((Peak) peakList.dataAt(i)).getHeight();
     if(temp > max)
       max = temp;
      }

    return max;
  }
}
