package exp.twostep;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.Callable;


public class Worker implements Callable<double[]> {
	
	public static final int MET = 0;
	public static final int TF = 1;
	public static int num = 0;
	
	DataRepresent mrna;
	DataRepresent met;
	DataRepresent cnv;
	String tf;
	ArrayList<Pair<String, String>> geneMet;
	int thisNum;
	
	int mode;
	
	double[] returnVal;

	public Worker(String tf, DataRepresent mrna, DataRepresent met, DataRepresent cnv, ArrayList<Pair<String, String>> geneMet, int mode){//data and tf name
		this.tf = tf;
		this.mrna = mrna;
		this.met = met;
		this.cnv = cnv;
		this.geneMet = geneMet;
		this.returnVal = new double[geneMet.size()*2];
		this.mode = mode;
		this.thisNum = num++;
		Arrays.fill(this.returnVal, 0d);
		
	}
	
	
	@Override
	public double[] call() throws Exception {
		int count = 0;
		double[] tfdata = mrna.content.get(tf);
		double[] cnvdata = new double[tfdata.length];
		Arrays.fill(cnvdata, 0d);

		for (Pair<String, String> pair : geneMet){
			double[] metdata = met.content.get(pair.second);
			double[] genedata = mrna.content.get(pair.first);
			if (cnv.content.containsKey(pair.first)){
				cnvdata = cnv.content.get(pair.first);
			}
			double[][] a = new double[1][genedata.length];
//			System.arraycopy(genedata, 0, a[0], 0, genedata.length);
			a[0] = genedata;
			MI mi = new MI();
			

			
			double[][] b = new double[1][tfdata.length];
			double[][] c = new double[2][tfdata.length];
			switch (mode){
			case MET:
				b[0] = tfdata;
				c[0] = cnvdata;
				c[1] = metdata;
				break;
			case TF:
				b[0] = metdata;
				c[0] = cnvdata;
				c[1] = tfdata;
				break;
			}
			

			double[][] c0 = new double[1][genedata.length];
			for (int i = 0; i < c0.length; i++){
				Arrays.fill(c0[i], 0d);
			}
//			System.out.println("Tread" + this.thisNum);
//			System.out.println("a " + a.length + " " + a[0].length);
//			System.out.println("b " + b.length + " " + b[0].length);
//			System.out.println("c " + c.length + " " + c[0].length);
			
			int k = (int)Math.ceil(tfdata.length * 0.16);
//			PartialMutualInformation p = new PartialMutualInformation(k, tfdata.length);
			
			
			returnVal[count] = mi.partialMutualInformation(a, b, c0, k);//MI
			returnVal[count + geneMet.size()] = mi.partialMutualInformation(a, b, c, k);//cMI
			//System.out.println("Thread" + thisNum + ":" + tf + "," + pair.second + "," + pair.first + "=>" + "mi = " + returnVal[count] + " cmi = " + returnVal[count + geneMet.size()]);
			//System.out.println();
			count++;
			
			
		}
		//mi.dispose();
		System.out.println("Thead" + thisNum + "; TF = " + tf + " .Finished");
		return returnVal;
	}
	


}
