//=====================================================================
// File:    AnalysisView.java
// Class:   AnalysisView
// Package: AFLPgui
//
// Author:  James J. Benham
// Date:    August 11, 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.Choice;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.ScrollPane;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import AFLPcore.AnalysisMgr;
import AFLPcore.AnalysisOp;
import AFLPcore.Bin;
import AFLPcore.DataList;
import AFLPcore.FeatureList;
import AFLPcore.Gel;
import AFLPcore.Lane;

/**
 * This class is responsible for displaying methods to analyze a gel
 * and the results of the analysis. The analysis output is text, so
 * it is simply displayed in a text area. A choice box is provided to
 * switch between the different analysis methods. In addition to the
 * main panel, which contains the <code>TextArea</code>, this class has
 * a <code>ButtonBar</code> with controls and a <code>Bar</code> to
 * display its status. These should be displayed by whichever object is
 * displaying this. Also, this class expects to be contained by a 
 * <code>ScrollPane</code>. (To change this, modify the paint method.)
 *
 * @author James J. Benham
 * @version 1.0.0
 * @date August 11, 1998
 */

public class AnalysisView extends Panel implements ItemListener
{
  //Button bar stuff
  private static final int HORZ_SPACE = 5;
  private static final int CHOICE_WIDTH = 160;

  // Info Bar component parameters
  private static int LABEL_H_INSET = 5;
  private static int LABEL_V_INSET = 3;
  private static int LABEL_WIDTH   = 600;
  private static int LABEL_HEIGHT  = 18;

  // Text Area borders
  private static int H_BORDER = 10;
  private static int V_BORDER = 10;

  private TextArea  outputArea;
  private ButtonBar buttonBar;
  private Bar infoBar;
  private Label infoLabel;

  private Choice methodChoice;
  private String selection;

  private String output;

  private Gel gel;

  private Frame topWindow;

  /**
   * Create a new analysis view with the specified parent window. The
   * parent window is used as a parameter for dialog box.
   *
   * @param parentWin  the window that contains this class
   */
  public AnalysisView(Frame parentWin)
  {
    setLayout(null);
    setSize(420, 420);
    outputArea = new TextArea();
    add(outputArea);
    outputArea.setBounds(10, 10, 400, 400);

    topWindow = parentWin;

    // createButtonBar sets the selection
    createButtonBar();
    createInfoBar();
  }

  /**
   * This runs whatever analysis operation is selected, or the default
   * if none has been choosen yet. The output from that method is then
   * displayed in a text area.
   *
   * @param gel  the gel to analyze
   */
  public void init(Gel gel)
  {
    this.gel = gel;

    AnalysisOp currentMethod;

    currentMethod = (AnalysisOp) FeatureList.getAnalysisMgr().get(selection);

    output = currentMethod.analyze(gel);
    outputArea.setText(output);
    infoLabel.setText("Finished running " + selection);
  }

  /**
   * Gives the text currently displayed in the output text area.
   *
   * @return  the text
   */
  public String getText()
  {
    return outputArea.getText();
  }

  /**
   * Called to handle item events. It watches for the selection box
   * for the analysis method to change, and when it does, it
   * re-runs the analysis.
   */
  public void itemStateChanged(ItemEvent e)
  {
    if(e.getSource() == methodChoice)
      {
	selection = methodChoice.getSelectedItem();
	init(gel);
      }
  }

  /**
   * This is used to resize the text area. Note: it assumes that the
   * text area is contained by a <code>ScrollPane</code>. The size is
   * set so that it mostly fills the display area. No actually drawing is
   * handled here. Instead, the super is called.
   *
   * @param g   the graphics object that represents the drawable area of
   *            this component.
   *
   * @see java.awt.ScrollPane
   */
  public void paint(Graphics g)
  {
    //get some size stuff
    ScrollPane parent = (ScrollPane) getParent();
    Dimension containerSize = parent.getViewportSize();

    setLocation(0, 0);
    setSize(containerSize);
    
    int height = (containerSize.height - 2*V_BORDER - 
		  parent.getHScrollbarHeight());
    int width = (containerSize.width - 2*H_BORDER -
		 parent.getVScrollbarWidth());
    outputArea.setBounds(H_BORDER, V_BORDER, width, height);

    //parent.validate();

    // do all the real work
    super.paint(g);
  }

  /**
   * Gives the button bar used by this class.
   *
   * @return a button bar with components specific to this class, as
   *         wells as the standard new, open, save, and print buttons.
   */
  public ButtonBar getButtonBar()
  {
    return buttonBar;
  }

  /**
   * Creates the button bar associated with viewing the analysis.
   * It adds a choice box to the four buttons defined in the ButtonBar
   * class. The choice box is used to select the method of analysis
   */
  private void createButtonBar()
  {
    buttonBar = new ButtonBar();
    buttonBar.setBounds(0, 0, 640, 32);

    // Let the parent window handle the action event for the orignal
    // button bar components
    buttonBar.sendActionEventsTo((ActionListener) topWindow);

    methodChoice = new Choice();

    AnalysisMgr mgr = FeatureList.getAnalysisMgr();
    String names[] = mgr.getNames();
    for(int i=0; i < names.length; i++)
      methodChoice.add(names[i]);
    selection = mgr.getDefaultName();
    methodChoice.select(selection);
    
    buttonBar.add(methodChoice);
    int startX = buttonBar.getFreeHorzPos();
    methodChoice.setBounds(startX + HORZ_SPACE, ButtonBar.VERT_INSET,
			   CHOICE_WIDTH, ButtonBar.BUTTON_HEIGHT);
    startX += CHOICE_WIDTH + HORZ_SPACE;
    methodChoice.addItemListener(this);
  }

  /**
   * Gives the label that this class uses to provide status information.
   *
   * @return a bar containing the label described above.
   */
  public Bar getInfoBar()
  {
    return infoBar;
  }

  /**
   * Creates the status bar, which contains a label used to provide
   * info about this class to the user.
   */
  private void createInfoBar()
  {
    // create the label
    infoLabel = new Label("Analysis Info....");
    // create the bar, no bottom border.
    infoBar = new Bar(true, false);
    infoBar.setLayout(null);
    infoBar.add(infoLabel);
    infoLabel.setBounds(LABEL_H_INSET, LABEL_V_INSET,
			LABEL_WIDTH, LABEL_HEIGHT);
    infoBar.setBounds(0, 0, 600, FragmentMap.BAR_HEIGHT);
  }
}
