package org.gel.mauve.analysis;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.gel.mauve.XMFAAlignment;
import org.gel.mauve.XmfaViewerModel;
import org.gel.mauve.backbone.Backbone;
import org.gel.mauve.backbone.BackboneList;

public class IdentityMatrix {

	public static void export( XmfaViewerModel model, XMFAAlignment xmfa, BufferedWriter output ) throws IOException
	{
		int seq_count = model.getSequenceCount();
		
		for(int seqI=0; seqI<seq_count; seqI++){
			for(int seqJ=0; seqJ<seq_count; seqJ++){
				if(seqJ <= seqI){
					output.write("\t");
					continue;
				}
				int[][] dist_mat = SnpExporter.countSubstitutions(model, seqI, seqJ);
				
				long shared_len = 0;
				BackboneList bb_list = model.getBackboneList();
				Backbone[] bb_array = bb_list.getBackboneArray();
				for(int i=0; i<bb_array.length; i++){
					if(!bb_array[i].getSeqs()[seqI] || !bb_array[i].getSeqs()[seqJ]) continue;
					shared_len += bb_array[i].getLength();
				}
				
				long total_diffs = 0;
				for(int i=0; i<4; i++){
					for(int j=0; j<4; j++){
						total_diffs += dist_mat[i][j]; 
					}
				}
		
				float dist_01 = (float)total_diffs / (float)shared_len;
				String dist_string = "";
				if(seqJ > 0) dist_string += "\t";
				dist_string += dist_01;
				output.write(dist_string);
			}
			output.write("\n");
		}
		output.close();
	}

	public static void main(String[] args) {
		Options opts = new Options();
		opts.addOption( OptionBuilder
			.withArgName("alignment file")
			.hasArg()
			.withDescription("A required parameter specifying an XMFA format file generated by progressiveMauve")
			.isRequired()
			.create('f')
			);

		opts.addOption( OptionBuilder
				.withArgName("output file name")
				.hasArg()
				.withDescription("The name of the output file for the identity matrix")
				.isRequired()
				.create('o')
				);

		CommandLineParser parser = new GnuParser();
		CommandLine line=null;
		try{
			line = parser.parse( opts, args );
		}catch(org.apache.commons.cli.ParseException pe){
			HelpFormatter formatter = new HelpFormatter();
			formatter.printHelp( 
					"SnpExporter -f <XMFA alignment input> -o <SNP output>", opts);
			
			throw new RuntimeException("There was an error parsing your command-line options.  Please check them and try again.");
		}
		String alnmtFilePath = line.getOptionValue('f');
		String outputFilePath = line.getOptionValue('o');
		
		try {
			System.out.print("Loading alignment file...");
			XmfaViewerModel model = new XmfaViewerModel(new File(alnmtFilePath), null);
			System.out.println("Exporting SNPs...");
			model.setReference(model.getGenomeBySourceIndex(0));
			BufferedWriter bw = new BufferedWriter(new FileWriter(outputFilePath));
			export(model, model.getXmfa(), bw);
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(-1);
		}
		
	}
}
