/*  
 *  src/org/metaqtl/main/InfoMap.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.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;

import org.metaqtl.ChromCluster;
import org.metaqtl.Chromosome;
import org.metaqtl.IMetaQtlConstants;
import org.metaqtl.MapCluster;
import org.metaqtl.MetaDico;
import org.metaqtl.ChromCluster.ClusterGraph;
import org.metaqtl.bio.IBioGenome;
import org.metaqtl.bio.IBioLocus;

/**
 * 
 */
public class InfoMap extends MetaMain {
	
	private static final String VERSION = IMetaQtlConstants.VERSION; 
	
	private static final String syntax  =  "Syntaxe: ConsMap "+
											"[{-m, --mapdir}]] "+
											"[{-t, --mrkth}]] "+
											"[{-o, --outfile}]] "+
											MetaMain.generalUsage();
	
	public void printUsage() {
        System.err.println(syntax);
    }
	
	public void printHelp() {
		
		System.out.println("InfoMap, "+VERSION);
		System.out.println("Copyright (C) 2005  Jean-Baptiste Veyrieras (INRA)");
		System.out.println("ConsMap comes with ABSOLUTELY NO WARRANTY.  ");
		System.out.println("This is free software, and you are welcome  ");
		System.out.println("to redistribute it under certain conditions.");
		System.out.println();
		System.out.println(syntax);
		System.out.println();
        MetaMain.generalHelp();
        System.out.println();
        System.out.println("-m, --mapdir  : the location of the directory of the map files");
        System.out.println("-t, --mrkth   : threshold on the number of times a marker is observed");
        System.out.println("-o, --outfile : the output file location");
        
	}
	

	public static void main(String[] args) {
		
		InfoMap program = new InfoMap();
		
		program.initCmdLineParser();
		
		CmdLineParser parser = program.parser;
		
        CmdLineParser.Option amapDir  = parser.addStringOption('m', "mapdir");
        CmdLineParser.Option amrkThresh  = parser.addIntegerOption('t', "mrkth");
        CmdLineParser.Option aoutFile = parser.addStringOption('o', "outfile");
        
        program.parseCmdLine(args);
        
        // Mandatory
        String mapDir  	 =  (String)parser.getOptionValue(amapDir);
        Integer mrkThresh = (Integer)parser.getOptionValue(amrkThresh, new Integer(1));
        String outFile 	 =  (String)parser.getOptionValue(aoutFile);
        
        if (mapDir== null) {
        	System.err.println("[ ERROR ] No map directory defined : EXIT NOW");
        	System.exit(2);
		}
        if (outFile == null) {
        	System.err.println("[ ERROR ] No output file defined : EXIT NOW");
        	System.exit(2);
		}
        
        IBioGenome[] maps   = null;
        IBioGenome skeleton = null;
        IBioLocus[] dubious = null;
        MetaDico mrkDico = null;
        
		try {
			maps     = getMaps(mapDir);
		} catch (IOException e) {
			System.err.println(e.getMessage());
			System.exit(3);
		}
		
        if (maps == null) {
        	
        	System.err.println("[ ERROR ] Unable to read map files from " + mapDir);
        	System.exit(4);
        	
        }
		
        MapCluster mapCluster = new MapCluster();
        
        mapCluster.addAllMap(maps);
        
        ChromCluster[] chromClusters = mapCluster.getClusters();
        
        try {
        	
        	// Print out pairwise comparison results between maps per chromosome
	        FileOutputStream stream = new FileOutputStream(outFile+"_cmp.txt");
	        
	        for(int i=0;i<chromClusters.length;i++) {
	        	chromClusters[i].setMrkThresh(mrkThresh.intValue());
	        	chromClusters[i].fixCluster();
	        	ClusterGraph graph  = chromClusters[i].getGraph();
	        	if (graph!=null) {
	        		graph.summarize(stream);
		        }
	        }
	    	stream.close();
	    	
	    	stream = new FileOutputStream(outFile+"_mrk.txt");
	    	
	    	dumpMarkerInfo (chromClusters, stream);
	    	
	    	stream.close();
	    	
		} catch (IOException e) {
			System.err.println("[ ERROR ] Failed to write in file " + outFile);
			System.err.println(e.getMessage());
			System.exit(5);
		}
	

        
        System.exit(0);
		
	}
	
	private static void dumpMarkerInfo(ChromCluster[] chromClusters, OutputStream stream) {
		int i,j,k,nm,index[];
		ArrayList keys;
		Chromosome[] chroms;
		
		PrintWriter writer = new PrintWriter(stream);
		
		//Print out the marker information per chromosome
    	//stream = new FileOutputStream(outFile+"_mrk.txt");
    	for(i=0;i<chromClusters.length;i++)
    	{
    		nm = chromClusters[i].getMarkerNumber();
    		writer.println(">CR " + chromClusters[i].getName() +" NM="+nm);
    		chroms = chromClusters[i].getClusterMembers();
    		keys = new ArrayList(chroms.length);
    		for(j=0;j<chroms.length;j++)
    			keys.add(chroms[j].getMapName());
    		Collections.sort(keys);
    		index = new int[keys.size()];
    		writer.println("#");
			writer.println("# Table of the chromosomes");
			writer.println("#");
			for(j=0;j<keys.size();j++) {
				writer.println((j+1)+"\t"+keys.get(j));
				for(k=0;k<keys.size();k++) {
					if (chroms[k].getMapName().equals(keys.get(j))) { 
						index[j]=k;
						break;
					}
				}
			}
			writer.println("#");
			writer.println("# Table of markers");
			writer.println("#");
			writer.print("Marker\tOccurence");
			for(j=0;j<keys.size();j++)
				writer.print("\t"+(j+1));
			writer.println();
			for(j=0;j<nm;j++) {
    			String mrkName = chromClusters[i].getMarkerNameByIndex(j);
    			int occ        = chromClusters[i].getMarkerOccurence(j);
    			writer.print(mrkName+"\t"+occ);
    			for(k=0;k<keys.size();k++) {
    				writer.print("\t");
    				int id = chroms[index[k]].getMarkerIdxWithName(mrkName);
    				if (id>=0) writer.print("x");
    			}
    			writer.println();
    		}
			writer.println();
			writer.println();
    	}
    	
    	writer.close();
		
	}

}
