/**
 * Title:        ProAlign<p>
 * Description:  sequence alignment comparison program<p>
 * Copyright:    Copyright (c) Ari Loytynoja<p>
 * License:      GNU GENERAL PUBLIC LICENSE<p>
 * @see          http://www.gnu.org/copyleft/gpl.html
 * Company:      ULB<p>
 * @author Ari Loytynoja
 * @version 1.0
 */
package proalign;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.RenderingHints;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseListener;


//  Prints taxa names, holds the info of sequences to remove.  
//
public class PrintNames extends JPanel {

    final Color bg = Color.white;
    final Color fg = Color.black;
    final Color blue = new Color(205,205,255);
    
    int verticalCharSpace;
    int horizontalCharSpace = 1;
    
    Font printFont;
    FontMetrics currentMetrics;
    
    int columnWidth, rowHeight; 
    int totalWidth, totalHeight;
    int charWidth, charHeight;
    
    int startSite = -1;

    boolean isNamesGiven = false;

    boolean[] taxaRemoved = new boolean[0];
    
    String textArray[];

    PrintNames pn;
    JScrollPane sPane = null;
    
    public PrintNames() { 
	
	setBackground(bg);
	setForeground(fg);
	
    }
    
    public PrintNames(String[] textArray, boolean isAligned) {

	pn = this;
	this.textArray = textArray;

	verticalCharSpace = ResultWindow.verticalCharSpace;

	isNamesGiven = true;

	taxaRemoved = new boolean[textArray.length];

	this.setParameters();

	totalWidth = textArray[0].length()*columnWidth+horizontalCharSpace;
	totalHeight = textArray.length*rowHeight+verticalCharSpace;
	setPreferredSize(new Dimension(totalWidth,totalHeight));

	if(isAligned) {
	    addMouseListener(new MiceListener());
	}

    }

    void setParameters() {

	printFont = new Font("monospaced", Font.PLAIN, ResultWindow.rwFontSize);
	
	setBackground(bg);
	setForeground(fg);
	
	currentMetrics = pn.getFontMetrics(printFont);
	charWidth = currentMetrics.charWidth(' ');
	charHeight = currentMetrics.getHeight();

	columnWidth = charWidth + horizontalCharSpace;      
	rowHeight = charHeight + verticalCharSpace;

    }
    
    public void paint(Graphics g) {
	
	if(isNamesGiven) {

	    if(printFont.getSize()!=ResultWindow.rwFontSize || 
	       verticalCharSpace!=ResultWindow.verticalCharSpace){
		
		printFont = new Font("monospaced", Font.BOLD, ResultWindow.rwFontSize);
		verticalCharSpace=ResultWindow.verticalCharSpace;
		
		this.setParameters();
	    }

	    totalWidth = Math.max(textArray[0].length()*columnWidth+
				  horizontalCharSpace,sPane.getWidth());
	    totalHeight = Math.max(textArray.length*rowHeight+
				   verticalCharSpace,sPane.getHeight());
	    setPreferredSize(new Dimension(totalWidth,totalHeight));
	    
	    int startX = sPane.getHorizontalScrollBar().getValue();
	    int endX = startX + sPane.getWidth();
	    int startY = sPane.getVerticalScrollBar().getValue();
	    int endY = startY + sPane.getHeight();
	    
	    int startColumn = (int) (startX/columnWidth);
	    int endColumn = Math.min((int)(endX/columnWidth)+1,textArray[0].length());
	    int startRow = (int) (startY/rowHeight);
	    int endRow = Math.min((int)(endY/rowHeight)+1,textArray.length);
	    
	    int charX = startColumn*columnWidth;
	    int charY = rowHeight+startRow*rowHeight;
	    
	    Graphics2D  g2 = (Graphics2D) g;
	    g2.setColor(bg);
	    g2.setFont(printFont);
	    g2.fillRect(Math.max(startX-10,0),Math.max(startY-10,0),
			Math.min(endX+10,totalWidth),
			Math.min(endY+10,totalHeight));
	    
	    for (int i = startRow; i < endRow; i++) {
		String str = textArray[i];
		for (int j = startColumn; j < endColumn; j++) {
		    // Do only once...
		    if (j == startColumn) {
			if (i < taxaRemoved.length) {
			    if (taxaRemoved[i]) {
				g2.setColor(blue);
				g2.fillRect(0,(charY-rowHeight+3),totalWidth,charY+3);
			    } else {
				g2.setColor(bg);
				g2.fillRect(0,(charY-rowHeight+3),totalWidth,charY+3);
			    }
			    g2.setColor(fg);
			}
		    }
		    // ..until here.
		    g2.drawString(""+str.charAt(j), charX, charY);
		    charX += columnWidth;
		}
		charX = startColumn * columnWidth ;
		charY += rowHeight;
	    }
	}
    }

    // Click on a name excludes/includes the taxon.
    //
    class MiceListener extends MouseAdapter {
	public void mouseClicked(MouseEvent e) {
	    int x = e.getX();
	    int y = e.getY();
	    if(e.isShiftDown()) {
		pn.updateTaxonList(x,y,true);
	    } else {
		pn.updateTaxonList(x,y,false);
	    }
	}
    } 

    // Taxa list kept up-to-date.
    //
    void updateTaxonList(int x, int y, boolean shiftDown) {

	if(shiftDown) {
	    if(startSite > 0) {
		int site = (int) y/rowHeight; 
		int start, end;
		if(startSite>site) {
		    start = site;
		    end = startSite;
		} else {
		    start = startSite+1;
		    end = site+1;
		}
		end = Math.min(end,taxaRemoved.length);
		for(int sx=start; sx<end; sx++) {
		    if (taxaRemoved[sx])
			taxaRemoved[sx] = false;
		    else 
			taxaRemoved[sx] = true;
		}
		pn.repaint();

		startSite = -1;
	    } else {
		int site = (int) y/rowHeight;
		
		    if (taxaRemoved[site])
			taxaRemoved[site] = false;
		    else 
			taxaRemoved[site] = true;
		    pn.repaint();

		    startSite = site;
		}


	} else {
	    int taxon = (int) y/rowHeight;
	    
	    taxon = Math.min(taxon,taxaRemoved.length-1);
	    if (taxaRemoved[taxon])
		taxaRemoved[taxon] = false;
	    else 
		taxaRemoved[taxon] = true;
	    pn.repaint();

	    startSite = -1;
	}
    }

    public boolean[] getRemovedTaxa() {
	return taxaRemoved;
    }  
}











