/**
 * 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 java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseListener;

//  Print a tree on a JPanel.
// 
public class PrintTree extends JPanel {

    int xBase, yBase, xMove, yMax, xMax, rowHeight;
    int cs = 3; // circleSize
    static int numOpenWindows = 0;
    
    boolean isTreeGiven = false;

    AlignmentNode root;
    ResultWindow rw;
    PrintTree pt; 
    QualityWindow currentQw;

    PrintTree() {    

	setBackground(Color.white);
	setForeground(Color.black);

    }

    PrintTree(AlignmentNode root, ResultWindow rw, boolean isAligned) {

	this.root = root;
	this.rw = rw;
	pt = this;

	isTreeGiven = true;
	
	this.setParameters();
	    
	setPreferredSize(new Dimension(rw.splitWidth, yMax));
	

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

    }    

    void setParameters() {

	setBackground(Color.white);
	setForeground(Color.black);

	rowHeight = rw.seqname.rowHeight;
	yMax = 4+root.getNumChild()*rowHeight;
	xMax = rw.splitWidth-10;
	yBase = 2+root.child[0].getNumChild()*rowHeight;
	xBase = 5;
	xMove = xMax/(root.getTreeDepth());	

    }

    public void paintComponent(Graphics g) {

	Graphics2D  g2 = (Graphics2D) g;
	super.paintComponent(g2);      //clears the background

	if(isTreeGiven) {

	    if(rowHeight!=rw.seqname.rowHeight) {
		this.setParameters();
	    }

	    setPreferredSize(new Dimension(rw.sPane1.getWidth(), yMax));
	    xMax = rw.sPane1.getWidth()-10;
	    xMove = xMax/(root.getTreeDepth());
	    
	    paintBranch(g2,root,yBase,xBase);
	    g2.drawLine(xBase-2,yBase,xBase,yBase);
	}
    }
    
    // Called from 'paintComponent'. Calls recursively itself.
    //
    public void paintBranch(Graphics2D g2, AlignmentNode node, int y, int x) {

	int nc0 = 0; int nc1 = 0; // number of child nodes
	if(node.child[0].getNumChild() > 1) {
	    nc0 = node.child[0].child[1].getNumChild();
	} 
	if(node.child[1].getNumChild()> 1) {
	    nc1 = node.child[1].child[0].getNumChild();
	}

	g2.fillOval(x-cs,y-cs,cs*2,cs*2);
	node.setTreeXY(x,y);
	g2.drawString(""+node.nodeNumber,x+cs*2,y+4);

	if(nc0>0) {
	    g2.drawLine(x,y,x,y-nc0*rowHeight);
	    g2.drawLine(x,y-nc0*rowHeight,x+xMove,y-nc0*rowHeight);
	    paintBranch(g2,node.child[0],y-nc0*rowHeight,x+xMove);	    
	} else {
	    g2.drawLine(x,y,x,y-rowHeight/2);
	    g2.drawLine(x,y-rowHeight/2,xMax,y-rowHeight/2);
	}
	if(nc1>0) {
	    g2.drawLine(x,y,x,y+nc1*rowHeight);
	    g2.drawLine(x,y+nc1*rowHeight,x+xMove,y+nc1*rowHeight);
	    paintBranch(g2,node.child[1],y+nc1*rowHeight,x+xMove);
	} else {
	    g2.drawLine(x,y,x,y+rowHeight/2);
	    g2.drawLine(x,y+rowHeight/2,xMax,y+rowHeight/2);
	}
    }

    // A click on a node opens an alignment quality window.
    //
    public void openQualityWindow(String name, boolean newWindow) {

	// ifShiftDown, open a new window.
	//
	if(!newWindow) {
	    if(numOpenWindows==0) {
		QualityWindow qw = new QualityWindow(root, name,rw);
		qw.setSize(600,100);
		qw.setLocation(200,300);
		qw.setTitle("Posterior probability of "+name);
		qw.setVisible(true);
		currentQw = qw;
		numOpenWindows++;
	    } else {
		currentQw.upDateData(root, name);
		currentQw.setTitle("Posterior probability of "+name);
	    }
	} else {
	    QualityWindow qw = new QualityWindow(root, name,rw);
	    qw.setSize(600,100);
	    qw.setLocation(220,320);
	    qw.setTitle("Posterior probability of "+name);
	    qw.setVisible(true);
	    currentQw = qw;
	    numOpenWindows++;
	}
    }

    
    class MiceListener extends MouseAdapter {
	public void mouseClicked(MouseEvent e) {
	    int x = e.getX();
	    int y = e.getY();
 	    String name = root.getNodeNameAtXY(x,y);
	    if(!name.equals("")) {
		AlignmentNode node = root.getNodeNamed(name);
		if(node.name.equals(name)) {
		    if(e.isShiftDown()) {
			pt.openQualityWindow(name,true);
		    } else {
			pt.openQualityWindow(name,false);
		    }
		}
		rw.messageText.setText(" viterbi:"+node.viterbiEnd+
				       "; forward: "+node.forwardEnd);
	    }
	}
    }
}













