package particlefiltering;
import fr.lip6.classifier.SMOSVM;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import javax.imageio.ImageIO;
import parameters.tracking_arguments;
import preprocessing.Parser;


public class pfThread extends Thread {

	particle[] p;
	BufferedImage image;
	int iframe;
	int box;
	tracking_arguments tracking_parameters;

	boolean finished = false;

	public particle[] process (BufferedImage image, particle[] p, int iframe, int box) throws FileNotFoundException, ClassNotFoundException, IOException {

		Parser parser = new Parser();
		
		ArrayList<String> hog_parameters_similarity = parser.Get_Array_List (tracking_parameters.hog_parameters_similarity);
		
		ArrayList<String> hog_parameters_svm = parser.Get_Array_List (tracking_parameters.hog_parameters_trained);
			
		SMOSVM<double[]> cls = null;
		try {
			ObjectInputStream obj = new ObjectInputStream(new FileInputStream(tracking_parameters.hog_obj));
			cls = (SMOSVM<double[]>) obj.readObject();
			obj.close();
		}
		catch (Exception e){
			e.printStackTrace();
		}
		
		int width = image.getWidth();
		int height = image.getHeight();
		particles P = new particles();
		
		int number_of_particles = tracking_parameters.number_of_particles;

		Random rng = new Random();

		for(int j = 0; j < number_of_particles; j++ ) {
					
			observation Obs = new observation(); 
			
			//System.out.printf("Particle : %d\n", j);
			
			p[j] = P.transition( p[j], width, height, rng, tracking_parameters);
			
			double s = p[j].get_s();
			
			p[j].set_weight ( Obs.likelihood ( 
					             image, 
					             Math.round((float)(p[j].get_y())), 
					             Math.round((float)(p[j].get_x())), 
					             Math.round((float)(p[j].get_width() * s)), 
					             Math.round((float)(p[j].get_height() * s)), 
					             p[j].get_histo(),
					             tracking_parameters,
					             hog_parameters_similarity,
					             hog_parameters_svm,
					             cls)); 
			
			
			//System.out.printf("particle %d weight : %f - %f %f %d %d\n", j, p[j].get_weight(), p[j].get_x(), p[j].get_y(), p[j].get_width(), p[j].get_height());
			
			/*int r = Math.round((float)(p[j].get_y()));
			int c = Math.round((float)(p[j].get_x()));
			int w = Math.round((float)(p[j].get_width() * s));
			int h = Math.round((float)(p[j].get_height() * s)); */
			
			//BufferedImage tmp = image.getSubimage(c - w / 2, r - h / 2, w, h);
			  
			//System.out.println("./out/"+String.format("%05d", iframe)+"/box_"+String.format("%02d", box)+"_particle_"+String.format("%03d", j)+".png");
			
			//ImageIO.write(tmp, "png", new File("./out/"+String.format("%05d", iframe)+"/box_"+String.format("%02d", box)+"_particle_"+String.format("%03d", j)+".png"));
			
			//System.out.printf("box : %d, particle: %d, x : %f, y : %f, w :%d, h : %d, s: %f, n_w : %f, n_h : %f, weight : %f\n\n", box, j, p[j].get_x(), p[j].get_y(), p[j].get_width(), p[j].get_height(), s, p[j].get_width()*s, p[j].get_height()*s, p[j].get_weight());
		}
		
		P.normalize_weights(p, number_of_particles, box);
		
		p = P.resample(p, number_of_particles); 
		
		comparator c = new comparator(); 
		
		Arrays.sort(p, c); 
		
		/*for(int j = 0; j < number_of_particles; j++ ) {
			System.out.printf("After normalization particle %d weight : %f - %f %f %d %d\n", j, p[j].get_weight(), p[j].get_x(), p[j].get_y(), p[j].get_width(), p[j].get_height());
		}*/
			
		
		//System.out.printf("####### Escolhida \n box: %d, particle: %d, x : %f, y : %f, w :%d, h : %d, s: %f, n_w : %f, n_h : %f, weight : %f\n\n", box, 0, p[0].get_x(), p[0].get_y(), p[0].get_width(), p[0].get_height(), p[0].get_s(), p[0].get_width()*p[0].get_s(), p[0].get_height()*p[0].get_s(), p[0].get_weight());
		
		/*int r1 = Math.round((float)(p[0].get_y()));
		int c1 = Math.round((float)(p[0].get_x()));
		int w1 = Math.round((float)(p[0].get_width() * p[0].get_s()));
		int h1 = Math.round((float)(p[0].get_height() * p[0].get_s())); */
		
		//BufferedImage tmp = image.getSubimage(c1 - w1 / 2, r1 - h1 / 2, w1, h1); 
		
		//ImageIO.write(tmp, "png", new File("./out/"+String.format("%05d", iframe)+"/box"+String.format("%02d", box)+"_escolhida.png"));
	
		return p;
	}

	public pfThread(BufferedImage image, particle[] p, int iframe, int box, tracking_arguments tracking_parameters) {
		this.image = image;
		this.p = p;
		this.iframe = iframe;
		this.box = box;
		this.tracking_parameters = tracking_parameters;
	} 

	public void run() {
		try {
			p = process (image, p, iframe, box); 
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finished = true;
	}

	public boolean hasFinished() {
		return finished;
	}

	public particle[] getParticles() {
		return p;
	}
	
}

