/**
 * Title:        ProAlign<p>
 * Description:  <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 java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.io.DataInputStream;
import java.io.BufferedInputStream;

/**
 * Running native ClustalW.
 */
public class RunClustalw extends Thread {


    String tempFolder;
    String clustalwPath;
    String cmdParameter;

    ResultWindow rw;

    Process process;
    DataInputStream clustalwOut;

     /**
     * Argument list describing the ClustalW loop.
     */
    RunClustalw(ResultWindow rw) {
	
	this.rw = rw;

	ProAlign.log("RunClustalw");

	clustalwPath = ProAlign.clustalwPath;
	tempFolder = ProAlign.tempFolder+File.separator;

	if(System.getProperty("os.name").startsWith("Windows")){
	    File oldFile = new File(tempFolder+"PROALIGN.TRE");
	    if(oldFile.exists()) {
		try {
		    oldFile.delete();
		} catch (Exception ie) {
		    ProAlign.log.println(" can not delete old guide tree-file!");
		}
	    }
	} else {
	    File oldFile = new File(tempFolder+"proalign.tre");
	    if(oldFile.exists()) {
		try {
		    oldFile.delete();
		} catch (Exception ie) { 
		    ProAlign.log.println(" can not delete old guide tree-file!");
		}
	    }
	}

	if(System.getProperty("os.name").startsWith("Windows")){
	    cmdParameter = "clustalw /tree /newtree="+tempFolder+"PROALIGN.TRE /infile="+
		tempFolder+"proalign.seq";
	} else {
	    cmdParameter = " -tree -newtree="+tempFolder+"proalign.tre -infile="+
		tempFolder+"proalign.seq";
	}
	
	start();
    }

    public void run(){
	/** 
	 *  Clustalw - make guide tree only!
	 */
	if(System.getProperty("os.name").startsWith("Windows")) {


	    int narg = numArg(cmdParameter,"/");
	    try {
		WinClustalw wc = new WinClustalw(narg,cmdParameter);
		
		while(wc.running) {
		    try{
			Thread.currentThread().sleep(500);
		    } catch(InterruptedException e) {}
		}
	    } catch(Exception ex) {
		ProAlign.log("WinClustalw error");
	    }

	} else {
	    try {

		process = Runtime.getRuntime().exec(clustalwPath+cmdParameter);
		clustalwOut = 
		    new DataInputStream(new BufferedInputStream(process.getInputStream()));
		
		String str;	
		while((str = clustalwOut.readLine()) != null) {         
		    if (str.length() > 0) {
			ProAlign.log(str);
		    }
		}
	    } catch(IOException e) { }  
	}
	if(ProAlign.DEBUG) {
	    ProAlign.log.flush();
	}
	
	String filepath;
	if(System.getProperty("os.name").startsWith("Windows")){
	    filepath = ProAlign.tempFolder+File.separator+"PROALIGN.TRE";
	} else {
	    filepath = ProAlign.tempFolder+File.separator+"proalign.tre"; 
	}
	
	File newFile = new File(filepath);
	if(!newFile.exists()) {  // for some reason ClustalW failed.

	    String text = "\n      ClustalW output not found!\n";
	    OpenDialog od = new OpenDialog(rw);
	    od.showDialog("Error!", text);
	    rw.setRawData(rw.seqs);
	    rw.setScrollPanes();
	    
	} else { // guide tree is fine.

	    TreeReader tr = new TreeReader();
	    String[] treeNodes = tr.getAllNodes(filepath);
	    CheckTreeAndData chk = new CheckTreeAndData(treeNodes, rw.seqs);

	    if(chk.nodesAreSame()) {
		String tree = tr.readFile(filepath);
		TreeNode tn = new TreeNode(tree);
		tree = tn.findMiddlePoint();

		rw.setRawDataAndTree(tree);
		rw.setScrollPanes();
		
	    } else {

		String text = new String("\n   Guide tree and sequence \n"+
					 "    file do not match!\n");
		OpenDialog od = new OpenDialog(rw);
		od.showDialog("Warning!", text); 

		ProAlign.log.println("ClustalW: nodes and names do not match!");

	    }
	}
    }

    public int numArg(String cmnd,String csep) {
        int narg = 0;
        for(int i = 0, j = 0; i < cmnd.length();) {
            j = cmnd.indexOf(csep, i);
            if (j >= i){
                narg++;
                i = j;
            }
            i++;
        }
        return narg;
    }
}















