package mosaik;

import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import javax.imageio.ImageIO;

import util.Tools;
import util.simpleIO.Out;

import dataBase.DataBase;
import dataBase.TimedAction;
import dataBase.subPicture.SubPicture;

public class CopyOfMosaikFunctions {
	
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		
		int partsX = 200;
		int partsY = 60;
		File searchPicFile = new File("./testdaten/big/_8147226.JPG");
		//File searchPicFile = new File("./testdaten/big/_8147228.JPG");
		File dbFile        = new File("./testdaten/alt/DataBase0.db");
		
		BufferedImage mosaikImage = makeMosaik(searchPicFile, dbFile, partsX, partsY, 1f);
		ImageIO.write(mosaikImage, "jpg", new File("mosaikImage.jpg"));
		Out.pl("Fertig....File gespeichert"); 
	}
	
	public static void makeDatabase(File dir, File dbFile) throws IOException{
		
		DataBase db = new DataBase(dir);
		ObjectOutputStream obj_out = new ObjectOutputStream( new FileOutputStream(dbFile) );
		obj_out.writeObject(db);
		obj_out.close();
	}
	
	public static BufferedImage makeMosaik(final File searchPicFile, File dbFile, int partsX, int partsY, float resize) throws FileNotFoundException, IOException, ClassNotFoundException{
		
		if(dbFile==null)
			dbFile = new File("defaultDB.db");
		
		Out.pl("> Load searchPicFull:");
		final BufferedImage searchPicFull = ImageIO.read(searchPicFile);
		int w = searchPicFull.getWidth(), h = searchPicFull.getHeight();
		final int sliceWidth=(int)(w/partsX+0.5f), sliceHeight=(int)(h/partsX+0.5f);
		
		Out.pl("> Load DB:");
		ObjectInputStream obj_in = new ObjectInputStream( new FileInputStream(dbFile) );
		Object obj = obj_in.readObject();  
		final DataBase db = (DataBase) obj;
		Out.pl("  "+db.toString());
		
		Out.pl("> Search:");
		int processors = Tools.getAvailableProcessors();
		//File imageFile = new File("testdatenfinalImg.jpg");
		//File imageFile = new File(folder+"1.jpg");
		//BufferedImage searchPic = ImageIO.read(searchPicFile);
		
		final BufferedImage finalImg = new BufferedImage(sliceWidth*partsX, sliceHeight*partsY, BufferedImage.TYPE_INT_RGB); 
		final Graphics2D finalGraphic = finalImg.createGraphics();
		finalGraphic.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); 
		Thread[] threads = new Thread[processors];
		//TODO
		int threadIndex=0;
		//int num = 0;  
		for (int y = 0; y<partsY; y++) {  
			Out.pl("> Search up pic["+y+"][x]... ");
			
			for (int x = 0; x<partsX; x++) {  
				
				final int offsetX = sliceWidth*x;
				final int offsetY = sliceHeight*y;
				//final int xFinal = x;
				//final int yFinal = y;
				
				waitForThread(threads, threadIndex);
				final int threadID = threadIndex;
				threads[threadIndex] = new TimedAction(0) {
					
					@Override
					public void action() throws Exception {
						SubPicture searchPic = new SubPicture(searchPicFile, searchPicFull, offsetX, offsetY, sliceWidth, sliceHeight);
						SubPicture pic = db.search(searchPic, threadID).get(0);		// get best result

						BufferedImage picFull = ImageIO.read(pic.imageFile);
						//Out.pl("> Searched up pic["+y+"]["+0+"] '"+pic.imageFile.getName()+"'");
						
						finalGraphic.drawImage(picFull, offsetX, offsetY, sliceWidth, sliceHeight, null);
					}
				};

				threadIndex = (threadIndex+1) % threads.length;
				//num++;  
			}  
		}  
		
		return finalImg;
	}
	
	private static void waitForThread(Thread[] threads, int i){
		
		if(threads[i]!=null && threads[i].isAlive()){
			try {
				threads[i].join();
			} catch (InterruptedException e) {
				// ignore
			}
		}
	}
	
}
