/*
 *This library is free software; you can redistribute it and/or
 *modify it under the terms of the GNU Lesser General Public
 *License as published by the Free Software Foundation; either
 *version 2.1 of the License, or (at your option) any later version.
 *
 *This library 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
 *Lesser General Public License for more details.
 *
 *You should have received a copy of the GNU Lesser General Public
 *License along with this library; if not, write to the Free Software
 *Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/* 
 * This software was written by Julian Selley (j.selley@man.ac.uk)
 * whilst at the University of Manchester as a Research Assistant. 
 *
 * The initial code base is copyright by the University of Manchester. 
 * Modifications to the initial code base are copyright of their 
 * respective authors, or their employers as appropriate. Authorship 
 * of the modifications may be determined from the ChangeLog placed 
 * at the end of this file
 */

package uk.ac.man.bioinf.gui.viewer; // Package name inserted by JPack

import java.awt.Color;
import java.awt.Graphics;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import uk.ac.man.bioinf.sequence.Element;
import uk.ac.man.bioinf.sequence.geom.SequenceAlignmentPoint;


/**
 * MultiplexerFastAlignmentViewerCellRenderer.java
 *
 * This multiplexer uses three other cell renderers to render the cell.
 * The reason for this is that as the size of the cell changes, it is
 * necessary to alter what is drawn.
 * <p>
 * As a result, this renderer listens to the
 * <code>JAlignmentViewer</code> for alterations to the size of the
 * cell.
 * <p>
 * The big disadvantage to this renderer may prove its downfall - it
 * has to make three function calls to draw the cell at normal size.
 *
 * Created: Fri Sep 15 19:21:54 2000
 *
 * @author Julian Selley
 * @version $Id: MultiplexerFastAlignmentViewerCellRenderer.java,v 1.6 2001/04/11 17:04:42 lord Exp $
 */

public class MultiplexerFastAlignmentViewerCellRenderer 
  implements FastAlignmentViewerCellRenderer, PropertyChangeListener
{
  private JAlignmentViewer viewer;
  
  // the cell renderers to be used to render the cell
  private ColorFastAlignmentViewerCellRenderer color;
  private BorderFastAlignmentViewerCellRenderer border;
  private TextFastAlignmentViewerCellRenderer text;
  private FastAlignmentViewerCellRenderer[] viableRenderers;
  
  private int cellWidth, cellHeight;

  /* (PENDING: JNS) 15.9.00 Currently, this is only dealing with one
   * size (i.e., not height *and* width). It may be that at a later
   * stage we will need to split these, but for the moment I see no
   * reason.
   */
  protected void calculateViableRenderers(int cellSize) 
  {
    /* NB: hard coded values for the cut offs. It isnt necessary to be
     * able to change these values currently on the fly.
     *
     * Consequently, if the cell size is smaller than 4, then only the
     * color renderer is used. If the cell size is between 4 and 8,
     * then the color and border renderers are used. Any greater
     * values and all three renderers are used.
     *
     * If it becomes necessary for a different rendering model then
     * this can be rewritten.
     */
    if (cellSize < 6) {
      viableRenderers = new FastAlignmentViewerCellRenderer[1];
      viableRenderers[0] = color;
    } else if (cellSize < 16) {
      viableRenderers = new FastAlignmentViewerCellRenderer[2];
      viableRenderers[0] = color;
      viableRenderers[1] = border;
    } else {
      viableRenderers = new FastAlignmentViewerCellRenderer[3];
      viableRenderers[0] = color;
      viableRenderers[1] = border;
      viableRenderers[2] = text;
    }
  }

  public MultiplexerFastAlignmentViewerCellRenderer(JAlignmentViewer viewer)
  {
    this.viewer = viewer;
    // become a listener of the viewer
    viewer.addPropertyChangeListener(this);

    // store the width and height of the cell for small optimizations
    this.cellWidth = viewer.getCellWidth();
    this.cellHeight = viewer.getCellHeight();

    // generate instances of the different viewers
    color = new ColorFastAlignmentViewerCellRenderer();
    border = new BorderFastAlignmentViewerCellRenderer();
    text = new TextFastAlignmentViewerCellRenderer();

    // calculate the dimension to use, based on which is smallest
    if (cellWidth < cellHeight)
      calculateViableRenderers(cellWidth);
    else
      calculateViableRenderers(cellHeight);
  }

  public void renderAlignmentViewerCell
    (Graphics g, int x, int y, int width, int height,
     JAlignmentViewer viewer, Element element,
     SequenceAlignmentPoint location, Color color,
     boolean isSelected, boolean hasFocus, boolean isAtPoint) 
  {
    // we need this check because this object is listening to the
    // JAlignmentViewer. 
    if( viewer != viewer ) throw new IllegalArgumentException
      ( "MultiplexerFastAlignmentViewer should only be used for a single JAlignmentViewer" );
    
    // pass the call to the relevant renderers
    for (int i = 0; i < viableRenderers.length; i++) 
      viableRenderers[i].renderAlignmentViewerCell
	(g, x, y, width, height, viewer, element, location, color,
	 isSelected, hasFocus, isAtPoint);
  }
  
  public void propertyChange(PropertyChangeEvent pce) 
  {
    if (pce.getPropertyName().equals("cellHeight") || pce.getPropertyName().equals("cellWidth" ) ){
      cellHeight = viewer.getCellHeight();
      cellWidth = viewer.getCellWidth();
      
      calculateViableRenderers( Math.min( cellWidth, cellHeight ) );
    }
  }
} // MultiplexerFastAlignmentViewerCellRenderer



/*
 * ChangeLog
 * $Log: MultiplexerFastAlignmentViewerCellRenderer.java,v $
 * Revision 1.6  2001/04/11 17:04:42  lord
 * Added License agreements to all code
 *
 * Revision 1.5  2001/03/12 16:34:12  lord
 * Alignment selection renderer added
 *
 * Revision 1.4  2001/01/04 14:59:42  lord
 * Displays selected alignments correctly
 *
 * Revision 1.3  2000/12/13 16:32:35  lord
 * Minor implementation improvements
 *
 * Revision 1.2  2000/09/21 18:39:35  jns
 * o altering the cell size at which the border renderer kicks in and out at, to
 * 6 from 10.
 *
 * Revision 1.1  2000/09/18 17:54:54  jns
 * o created a new multiplexer cell renderer to take account of cell size
 * o initial code
 *
 */
