/*  
 *  src/org/metaqtl/main/MQTLView.java
 * 
 *  $Author: veyrieras $, $Date: 2006-10-17 15:41:54 $, $Version$
 *
 *  MetaQTL : a Java package for QTL Meta-Analysis
 * 
 *  Copyright (C) 2003-2006  Jean-Baptiste Veyrieras, INRA, France.
 *
 *  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; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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 * 
 */
package org.metaqtl.main;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import org.metaqtl.Chromosome;
import org.metaqtl.IMetaQtlConstants;
import org.metaqtl.MetaQtlAnalysis;
import org.metaqtl.MetaQtlModel;
import org.metaqtl.MetaQtlResult;
import org.metaqtl.QtlPartition;
import org.metaqtl.adapter.ChromosomeAdapter;
import org.metaqtl.bio.IBioGenome;
import org.metaqtl.graph.ChromGraph;
/**
 * 
 */
public class MQTLView extends MetaMain {
	
	private static final String VERSION = IMetaQtlConstants.VERSION; 
	
	private static final String syntax  =  "Syntaxe: MetaDraw "+
											"[{-m, --map}]] "+
											"[{-c, --chrom}]] "+
											"[{-r, --clust}]] "+
											"[{-b, --best}]] "+
											"[{-t, --tree}]] "+
											"[{--mode}]] "+
											"[{-p, --par}]" +
											"[{--img}]" +
											"[{-o, --outstem}]] "+										
											MetaMain.generalUsage();
	
	public void printUsage() {
        System.err.println(syntax);
    }
	
	public void printHelp() {
		MetaMain.printLicense("TreeDraw", VERSION);
		System.out.println();
		System.out.println(syntax);
        System.out.println();
        MetaMain.generalHelp();
        System.out.println();
        System.out.println("-m, --map     : the XML file of the map");
        System.out.println("-c, --chrom   : the name of the chromosome (or a list seperated by comma)");
        System.out.println("-r, --clust   : the file location of the clustering result");
        System.out.println("-b, --best    : the file location of the best clusterings");
        System.out.println("-t, --tree    : the file location of the hierarchical clustering");
        System.out.println("    --mode    : the mode of representation");
        System.out.println("    --trait   : the name of the trait");
        System.out.println("-p, --par     : the file location of the plot parameters");
        System.out.println("-o, --outstem : the output stem");
        System.out.println("--img         : the format name of the image among this list");
        MetaMain.printImgFormat(16); 
	}
	
	public static void main(String[] args) {
		
		MQTLView program = new MQTLView();
		
		program.initCmdLineParser();
		
		CmdLineParser parser = program.parser;
		
        CmdLineParser.Option amapFile    = parser.addStringOption('m', "map");
        CmdLineParser.Option atreeFile   = parser.addStringOption('t', "tree");
        CmdLineParser.Option aclustFile  = parser.addStringOption('r', "clust");
        CmdLineParser.Option abestFile   = parser.addStringOption('b', "best");
        CmdLineParser.Option achromList  = parser.addStringOption('c', "chrom");
        CmdLineParser.Option aMode       = parser.addIntegerOption("mode");
        CmdLineParser.Option atraitName  = parser.addIntegerOption("trait");
        CmdLineParser.Option aparFile    = parser.addStringOption('p', "par");
        CmdLineParser.Option aimgFormat  = parser.addStringOption("img");
        CmdLineParser.Option aoutFile    = parser.addStringOption('o', "outdir");
        
        program.parseCmdLine(args);
        
        // Mandatory
        String mapFile  	 =  (String)parser.getOptionValue(amapFile);
        String treeFile  	 =  (String)parser.getOptionValue(atreeFile);
        String clustFile  	 =  (String)parser.getOptionValue(aclustFile);
        String bestFile  	 =  (String)parser.getOptionValue(abestFile);
        String chromList     =  (String)parser.getOptionValue(achromList);
        Integer mode         =  (Integer)parser.getOptionValue(aMode, new Integer(QtlPartition.VERTICAL_MODE));
        String traitName  	 =  (String)parser.getOptionValue(atraitName);
        String parFile  	 =  (String)parser.getOptionValue(aparFile);
        String imgFormat	 =  (String)parser.getOptionValue(aimgFormat, "jpeg");
        String outFile  	 =  (String)parser.getOptionValue(aoutFile);
        
        if (mapFile == null) {
        	System.err.println("[ ERROR ] : No map file defined");
        	System.exit(2);
		}
        if (clustFile == null && treeFile == null) {
        	System.err.println("[ ERROR ] : No clustering result defined");
        	System.exit(2);
        }
        if (clustFile != null && bestFile == null) {
        	System.err.println("[ ERROR ] : No best clustering model file defined");
        	System.exit(2);
        }
        if (clustFile == null && bestFile != null) {
        	System.err.println("[ ERROR ] : No clustering result file defined");
        	System.exit(2);
        }
        
        IBioGenome map					= null;
        MetaQtlAnalysis treeAnalysis	= null;
        MetaQtlAnalysis clustAnalysis	= null;
        MetaQtlModel bestClust			= null;
		String[] chromNames             = null;
        
        try {
			map  	 	   = getMap(mapFile);
        	treeAnalysis   = getResult(treeFile);
        	clustAnalysis  = getResult(clustFile);
        	bestClust      = getCluster(bestFile);
        	chromNames     = parseChromList(chromList);
        	setParameter(parFile);
		} catch (IOException e) {
			System.err.println(e.getMessage());
			System.exit(3);
		}
		if (map == null) {
			System.err.println("[ ERROR ] : Unable to load map from " + mapFile);
			System.exit(4);
		}
		if (clustAnalysis == null && treeAnalysis == null) {
			System.err.println("[ ERROR ] : Unable to load result");
			System.exit(4);
		}
		if (clustAnalysis == null && bestClust != null)  {
			System.err.println("[ ERROR ] : Unable to load result from " + clustFile);
			System.exit(4);
		}
		if (clustAnalysis != null && bestClust == null)  {
			System.err.println("[ ERROR ] : Unable to load best models from " + bestFile);
			System.exit(4);
		}
		
		Chromosome[] chromosomes = ChromosomeAdapter.toChromosomes(map);
		Chromosome[] chrom2draws = getChromByNames(chromosomes, chromNames);
		if (chrom2draws == null) chrom2draws = chromosomes;
		ChromGraph[] chromGraphs = getChromGraph(chrom2draws, clustAnalysis, bestClust, treeAnalysis, traitName, mode.intValue());
		
		if (chromGraphs != null) {
			try {
				File file = new File(outFile+"."+imgFormat);
				writeImg(chromGraphs, file, imgFormat);
				file = new File(outFile+".par");
				writePar(file);
			} catch (IOException e) {
 				System.err.println(e.getMessage());
				System.exit(5);
			}
 			System.exit(0);
		}
		
		System.err.println("[ ERROR ] : No chromosome to draw !");
		System.exit(6);
	 	
	 }
	 /**
	 * @param chrom2draws
	 * @param clustAnalysis
	 * @param bestClust
	 * @param treeAnalysis
	 * @return
	 */
	private static ChromGraph[] getChromGraph(Chromosome[] chromosomes, MetaQtlAnalysis clustAnalysis, MetaQtlModel bestClust, MetaQtlAnalysis treeAnalysis, String trait, int qtlMode) {
		ArrayList chromGraphList = new ArrayList();
		for(int i=0;i<chromosomes.length;i++) {
	 		if (clustAnalysis != null) {
	 			String[] traits = bestClust.getTraitNames(chromosomes[i].getName());
	 			for(int j=0;j<traits.length;j++) {
	 				if (trait==null || (trait.equals(traits[j]))) {
		 				ChromGraph chromGraph = new ChromGraph();
		 				int kclust  = bestClust.getModel(chromosomes[i].getName(), traits[j]);
		 				QtlPartition qtlPart = getQtlPartition(chromosomes[i], clustAnalysis, traits[j], kclust, 'P');
		 				if (treeAnalysis != null) {
		 					qtlPart.tree         = treeAnalysis.getResult(chromosomes[i].getName(), traits[j]).getQtlTree();
		 				}
		 				chromGraph.chromosome   = chromosomes[i];
		 				chromGraph.qtlPart      = qtlPart;
		 				if (qtlPart.tree == null)
		 					chromGraph.qtlPart.mode = qtlMode;
		 				else chromGraph.qtlPart.mode = QtlPartition.HORIZONTAL_MODE;
		 				chromGraphList.add(chromGraph);
	 				}
	 			}
	 		} else {
	 			MetaQtlResult[] results = treeAnalysis.getResults(chromosomes[i].getName());
	 			for(int j=0;j<results.length;j++) {
	 				if (trait==null || (trait.equals(results[j].trait))) {
		 				ChromGraph chromGraph = new ChromGraph();
		 				QtlPartition qtlPart  = getQtlPartition(chromosomes[i], treeAnalysis, results[j].trait, 1, 'P');
		 				chromGraph.chromosome   = chromosomes[i];
		 				chromGraph.qtlPart      = qtlPart;
		 				chromGraph.qtlPart.mode = QtlPartition.HORIZONTAL_MODE;
		 				chromGraphList.add(chromGraph);	
	 				}
	 			}
	 		}
	 	}
		if (chromGraphList.size()>0) {
			ChromGraph[] chromGraphs = new ChromGraph[chromGraphList.size()];
			chromGraphList.toArray(chromGraphs);
			return chromGraphs;
		}
		return null;
	}

	
}
