package sizeNormalization;

import GUI.FileChooser;
import GUI.internalFrame;
import GUI.mainWindow;
import ij.ImagePlus;
import ij.gui.NewImage;
import ij.process.ImageProcessor;
import java.awt.image.*;
import java.awt.Color;
import java.awt.Image;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.FileReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import kohonenSOM.SOMDemoCodebook;

public class MyAlgorithm {
	
	ImagePlus imp;
	ImagePlus imp2, imp3, imp4;
	ImageProcessor ip;
	ImageProcessor nip, nip2, nip3;
	AreaAveragingScaleFilter scale;
	ReplicateScaleFilter repScale;
	RescaleOp opScale;
	int numberResult;
	SOMDemoCodebook som2 = new SOMDemoCodebook();
	boolean draw;

	public MyAlgorithm(ImagePlus imp, ImageProcessor ip, int numberResult, boolean draw) {
		this.imp = imp;
		this.ip = ip;
		this.numberResult = numberResult;
		this.draw = draw;
	}
	
	public void run(int scale){
		
		int color = ((Color.red.getRed() & 0xff) << 16) + ((0 & 0xff) << 8) + (0 & 0xff); //red color
		int color2 = ((0 & 0xff) << 16) + ((0 & 0xff) << 8) + (Color.blue.getBlue() & 0xff); //blue color
		int color3 = ((0 & 0xff) << 16) + ((Color.green.getGreen() & 0xff) << 8) + (0 & 0xff); //green color
		
		ArrayList redIlines = new ArrayList();
		
		for (int j = 0; j < ip.getHeight(); j++) {			
			if (ip.getPixel(0, j) == color) {
				redIlines.add(j);
			}
		}
		
		ArrayList redItop = new ArrayList();
		ArrayList redIbottom = new ArrayList();
		ArrayList redJleft = new ArrayList();
		ArrayList redJright = new ArrayList();
		
		for (int i = 0; i < ip.getWidth(); i++) {	
			for (int j = 0; j < ip.getHeight(); j++) {	
				if (i != 0)
					if (((ip.getPixel(i, j) == color) || (ip.getPixel(i, j) == color2)|| (ip.getPixel(i, j) == color3)) && ((ip.getPixel(i-1, j) != color) && (ip.getPixel(i-1, j) != color2) && (ip.getPixel(i-1, j) != color3))){
						int index = -1;
						for (int k = 0; k < redIlines.size(); k++) {
							if (k != 0) {
								if ( ( (Integer)(redIlines.get(k)) > j ) && ( (Integer)(redIlines.get(k-1)) < j ) )
									index = k;
							} else {
								if ( ( (Integer)(redIlines.get(k)) > j ) )
									index = k;
							}
						}
						boolean find = false;
						int theNearest = 0;
						for (int k = 0; k < redJright.size(); k++) {
							if (( (Integer)(redJright.get(k)) == i ) && ( (Integer)(redIbottom.get(k)) == (Integer)(redIlines.get(index)) ))
								find = true;
							if ( (Integer)(redIbottom.get(k)) == (Integer)(redIlines.get(index)) )
								if ( (Integer)(redJright.get(k)) >  theNearest)
									theNearest = (Integer)(redJright.get(k));
						}
						if (!find) {
							redJright.add(i);
							redJleft.add(theNearest);
							if (index == 0)
								redItop.add(0);
							else 
								redItop.add((Integer)(redIlines.get(index-1)));
							redIbottom.add((Integer)(redIlines.get(index)));
						}
					}
				
			}
		}
		
		for (int i = 0; i < redIlines.size(); i++) {
			redJright.add(ip.getWidth());
			redJleft.add(redJleft.get(redJleft.size() - 1- i - i));
			redItop.add(redItop.get(redItop.size() -1 - i - i));
			redIbottom.add(redIbottom.get(redIbottom.size() -1 - i - i));
		//	System.out.println("top "+redItop.get(redItop.size() -1)+" bottom "+ redIbottom.get(redIbottom.size() - 1)+" left "+ redJleft.get(redJleft.size() - 1)+" right "+redJright.get(redJright.size() - 1));

		}
		int count = (int)(Math.sqrt(redJright.size())) + 1;
		ImagePlus impLast = NewImage.createRGBImage ("Normalization", count * scale, count * scale, 1, NewImage.FILL_WHITE);
		ImageProcessor nipLast = impLast.getProcessor();
/*		for (int i = 0; i < ip.getWidth(); i++) {
			for (int j = 0; j < ip.getHeight(); j++) {
				if ((ip.getPixel(i, j) == color) || (ip.getPixel(i, j) == color2) || (ip.getPixel(i, j) == color3))
					nip.putPixel(i, j, ip.getPixel(i, j));
			}
		}*/
		//System.out.println("start");
		int h = 0;
		int w = 0;
		ArrayList ww = new ArrayList();
		
		int pocet = 0;
//////////////////////////////////////////
		for (int q = 0; q < redJright.size(); q++) {
		
						//odstranenie zbytocnych bielych ploch
						int numberLeft = 0;
						int numberRight = 0;
						int numberTop = 0;
						int numberBottom = 0;
						boolean deleteLeft = true;
						boolean deleteRight = true;
						boolean deleteTop = true;
						boolean deleteBottom = true;
						
						
						int i = (Integer)(redJleft.get(q)) + 1;
						while ( (i < (Integer)(redJright.get(q))) && (deleteLeft) ) {
							int j = (Integer)(redItop.get(q)) + 1;
							while ( (j < (Integer)(redIbottom.get(q))) && (deleteLeft) ) {
								if (ip.getPixelValue(i, j) != 255)
									deleteLeft = false;
								j++;
							}
							if (deleteLeft)
								numberLeft++;
							i++;
						}
						
						i = (Integer)(redJright.get(q))-1;
						while ( (i > (Integer)(redJleft.get(q))) && (deleteRight) ) {
							int j = (Integer)(redItop.get(q)) + 1;
							while ( (j < (Integer)(redIbottom.get(q))) && (deleteRight) ) {
								if (ip.getPixelValue(i, j) != 255)
									deleteRight = false;
								j++;
							}
							if (deleteRight)
								numberRight++;
							i--;
						}	
						
						int j = (Integer)(redItop.get(q)) + 1;
						while ( (j < (Integer)(redIbottom.get(q))) && (deleteTop) ) {
							i = (Integer)(redJleft.get(q)) + 1;
							while ( (i < (Integer)(redJright.get(q))) && (deleteTop) ) {
								if (ip.getPixelValue(i, j) != 255)
									deleteTop = false;
								i++;
							}
							if (deleteTop)
								numberTop++;
							j++;
						}
						
						j = (Integer)(redIbottom.get(q)) -1;
						while ( (j > (Integer)(redItop.get(q))) && (deleteBottom) ) {
							i = (Integer)(redJleft.get(q)) + 1;
							while ( (i < (Integer)(redJright.get(q))) && (deleteBottom) ) {
								if (ip.getPixelValue(i, j) != 255)
									deleteBottom = false;
								i++;
							}
							if (deleteBottom)
								numberBottom++;
							j--;
						}
						
						//System.out.println("numberLeft "+numberLeft);
						//System.out.println("numberRight "+numberRight);
						//System.out.println("numberTop "+numberTop);
						//System.out.println("numberBottom "+numberBottom);
						
						//1. n*n
						int newWidth = (Integer)(redJright.get(q)) - (Integer)(redJleft.get(q)) - numberLeft - numberRight;
						int newHeight = (Integer)(redIbottom.get(q)) - (Integer)(redItop.get(q)) - numberTop - numberBottom;
						//System.out.println("newWidth "+newWidth);
						//System.out.println("newHeight "+newHeight);
						
						if ((newWidth > 0) && (newHeight > 0)) {
									if ( newWidth > newHeight )
										imp2 = NewImage.createRGBImage ("Normalization", newWidth, newWidth, 1, NewImage.FILL_WHITE);
									else
										imp2 = NewImage.createRGBImage ("Normalization", newHeight, newHeight, 1, NewImage.FILL_WHITE);
									nip = imp2.getProcessor();
									
			/*						for (i = numberLeft + (Integer)(redJleft.get(q)); i < (Integer)(redJright.get(q)) - numberRight; i++) {
										for (j = numberTop + (Integer)(redItop.get(q)); j < (Integer)(redIbottom.get(q)) - numberBottom; j++) {
											if ((ip.getPixel(i, j) != color) && (ip.getPixel(i, j) != color2) && (ip.getPixel(i, j) != color3))
												nip.putPixel(i - numberLeft, j - numberTop, ip.getPixel(i, j));
										}
									}*/
									
									for (i = numberLeft + (Integer)(redJleft.get(q)); i < (Integer)(redJright.get(q)) - numberRight; i++) {
										for (j = numberTop + (Integer)(redItop.get(q)); j < (Integer)(redIbottom.get(q)) - numberBottom; j++) {
											if ((ip.getPixel(i, j) != color) && (ip.getPixel(i, j) != color2) && (ip.getPixel(i, j) != color3))
												nip.putPixel(i - numberLeft - (Integer)(redJleft.get(q)), j - numberTop - (Integer)(redItop.get(q)), ip.getPixel(i, j));
										}
									}
									//38 * 38
									
									//scale = new AreaAveragingScaleFilter(38,38);
									repScale = new ReplicateScaleFilter(scale,scale);
								//	opScale = new RescaleOp(38,38);
									ImageProducer filteredImageSource = new FilteredImageSource(imp2.getImage().getSource(), repScale); 
									Image averimg;
									averimg = java.awt.Toolkit.getDefaultToolkit().createImage(filteredImageSource); 
									
									imp3 = new ImagePlus();
									imp3.setImage(averimg);
									nip2 = imp3.getProcessor();
									
									for (int k = 0; k < nip2.getWidth(); k++) {
										for (int index = 0; index < nip2.getHeight(); index++) {
											nipLast.putPixel((w*scale)+k, (h*scale)+index, nip2.getPixel(k, index));
										}
									}
									//create file
									try{
										//System.out.println("w "+w+", h "+h);
										FileWriter fw = new FileWriter("pics\\graphemes\\"+numberResult+"\\"+numberResult+"a"+w+"a"+h+".txt");
										BufferedWriter bw = new BufferedWriter(fw);
										for (int index = 0; index < scale; index++) {
											for (int k = 0; k < scale; k++) {
												if (nip2.getPixelValue(k, index) == 255)
													bw.write("1 ");
												else 
													bw.write("0 ");
											}
											bw.write("\n");
										}
										bw.close();
									} catch (Exception e) {
										System.out.println(e.getMessage());
									}
									//este raz 
									//create file
									try{
										//System.out.println("w "+w+", h "+h);
										FileWriter fw = new FileWriter("pics\\graphemes\\"+numberResult+"\\"+numberResult+"a"+pocet+".txt");
										BufferedWriter bw = new BufferedWriter(fw);
										for (int index = 0; index < scale; index++) {
											for (int k = 0; k < scale; k++) {
												if (nip2.getPixelValue(k, index) == 255)
													bw.write("1 ");
												else 
													bw.write("0 ");
											}
											bw.write("\n");
										}
										bw.close();
									} catch (Exception e) {
										System.out.println(e.getMessage());
									}									
									/////
									
									
									w++;
									if (w == (count)) {
										h++;
										ww.add(w);
										w=0;
									}
									
									pocet++;
						}
		}
		ww.add(w);
		//create file
		try{
			FileWriter fw = new FileWriter("pics\\graphemes\\"+numberResult+"\\info.txt");
			BufferedWriter bw = new BufferedWriter(fw);
			bw.write((count-1)+"\n");
			for (int i = 0; i < ww.size(); i++) {
				bw.write(Integer.toString((Integer)(ww.get(i)))+"\n");
			}
			bw.close();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		/////	
		
		//zapisem pocet
		//create file
		try{
			FileWriter fw = new FileWriter("pics\\graphemes\\"+numberResult+"\\info2.txt");
			BufferedWriter bw = new BufferedWriter(fw);
			bw.write(Integer.toString(pocet));
			bw.close();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		
		if (draw) {
			//nip
			mainWindow.intFrameArrayList.add(new internalFrame("Words Separation", impLast, FileChooser.number, numberResult, 1, true));
			try {
				//mainWindow.intFrame[FileChooser.number].setSelected(true);
				((internalFrame)(mainWindow.intFrameArrayList.get(FileChooser.number))).setSelected(true);
			} catch(Exception e){
				System.out.println("Chyba");
			}	
			++FileChooser.number;	
		}
	}
	
	
	public double run3(int scale, boolean setSelected){
		//System.out.println("numberResult "+numberResult);
		int[] h = new int[numberResult+1];
		int[][] w = new int[numberResult+1][0];
		int[] countGrapheme = new int[numberResult+1];
		
		for (int d = 0; d < numberResult+1; d++) {
			//nacitam si udaje z info.txt
			try{
				FileReader fw = new FileReader("pics\\graphemes\\"+d+"\\info.txt");
				BufferedReader bw = new BufferedReader(fw);
				String s;
				h[d]  = Integer.parseInt(bw.readLine());
				w[d] = new int[h[d]];
				int i = 0;
				while ((s = bw.readLine()) != null) {
					w[d][i] = Integer.parseInt(s);
					i++;
				}
				bw.close();
				fw.close();
			} catch (Exception e) {
				System.out.println("chyba "+e.getMessage());
			}

			for (int i = 0; i < w[d].length; i++) {
				countGrapheme[d] = countGrapheme[d] + w[d][i];
			}
			//for (int i = 0; i < countGrapheme.length; i++) {
				//System.out.println("countGrapheme[d] "+countGrapheme[d]);
			//}
		}

		///////////
		//spustim SOMku
		int countGraphemeAll = 0;
		for (int i = 0; i < countGrapheme.length; i++) {
			countGraphemeAll = countGraphemeAll + countGrapheme[i];
		}
		
		System.out.println("START SOMKA");
		double vysledokSOM = som2.run(countGrapheme, h, w, numberResult+1);
		System.out.println("KONIEC SOMKA");
		
		//spustim gargabe collector
		System.runFinalization();
		System.gc();
		
		//System.out.println("countGrapheme "+countGraphemeAll);
		String[] f = new String[countGraphemeAll];
		
		ImagePlus impLast = NewImage.createRGBImage ("Normalization", ((int)(Math.sqrt(countGraphemeAll))) * scale, (int)(Math.sqrt(countGraphemeAll)) * scale, 1, NewImage.FILL_WHITE);
		ImageProcessor nipLast = impLast.getProcessor();
		
		//for (int d = 0; d < numberResult; d++) {
			try{
				//FileReader fw = new FileReader("D://_Docs//ROBOTA//WORKSPACE-ECLIPSE//adel//pics//graphemes//codebook//vysl.txt");
				FileReader fw = new FileReader("pics//graphemes//codebook//vysl.txt");
				BufferedReader bw = new BufferedReader(fw);
				
				String line = bw.readLine();
				for (int i = 0; i < f.length; i++) {
					f[i] = line.substring(0, line.indexOf(' '));
					line = line.substring(line.indexOf(' ') + 1, line.length());
				}
				
				bw.close();
				fw.close();
			} catch (Exception e) {
				System.out.println(e.getMessage());
			}
			
			try{
				int hh = 0;
				int ww = 0;
				for (int i = 0; i < f.length; i++) {
					FileReader fw = new FileReader("pics//graphemes//"+f[i].substring(0, 1)+"//"+f[i]);
					BufferedReader bw = new BufferedReader(fw);
					
					for (int k = 0; k < scale; k++) {
						String line = bw.readLine();
						for (int index = 0; index < scale; index++) {
							int col = Integer.parseInt(line.substring(0, line.indexOf(' ')));
							int color = 0;
							if (f[i].substring(0, 1).compareTo("0") == 0)
								color = ((Color.red.getRed() & 0xff) << 16) + ((0 & 0xff) << 8) + (0 & 0xff);

							else 
								color = ((0 & 0xff) << 16) + ((0 & 0xff) << 8) + (Color.blue.getBlue() & 0xff);

							if (col == 0)
								nipLast.putPixel((ww*scale)+index, (hh*scale)+k, color);
							line = line.substring(line.indexOf(' ') + 1, line.length());
						}
					}
					ww++;
					if (ww == ((int)(Math.sqrt(countGraphemeAll)))) {
						hh++;
						ww=0;
					}
					bw.close();
					fw.close();
				}
				
			} catch (Exception e) {
				System.out.println(e.getMessage());
			}
		//}
		
		if (draw) {
			mainWindow.intFrameArrayList.add(new internalFrame("SOM", impLast, FileChooser.number, numberResult, 1, true));
			try {
				//mainWindow.intFrame[FileChooser.number].setSelected(true);
				((internalFrame)(mainWindow.intFrameArrayList.get(FileChooser.number))).setSelected(setSelected);
			} catch(Exception e){
				System.out.println("Chyba");
			}	
			++FileChooser.number;
		}
		
		return vysledokSOM;
///////////////////////
/*		impLast = NewImage.createRGBImage ("Normalization", h * scale, h * scale, 1, NewImage.FILL_WHITE);
		nipLast = impLast.getProcessor();
		
		try{
			int hh = 0;
			int ww = 0;
			for (int i = 0; i < f.length; i++) {
				FileReader fw = new FileReader("D://_Docs//ROBOTA//WORKSPACE-ECLIPSE//adel//pics//graphemes//"+numberResult+"//"+f[i]);
				BufferedReader bw = new BufferedReader(fw);
				
				for (int k = 0; k < scale; k++) {
					String line = bw.readLine();
					for (int index = 0; index < scale; index++) {
						int col = Integer.parseInt(line.substring(0, line.indexOf(' ')));
						if (col == 0)
							nipLast.putPixelValue((ww*scale)+index, (hh*scale)+k, col);
						line = line.substring(line.indexOf(' ') + 1, line.length());
					}
				}
				ww++;
				if (ww == (h)) {
					hh++;
					ww=0;
				}
				bw.close();
			}
			
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		
		
		
		mainWindow.intFrame[FileChooser.number] = new internalFrame("Words Separation", impLast, FileChooser.number, numberResult);
		try {
			mainWindow.intFrame[FileChooser.number].setSelected(true);
		} catch(Exception e){
			System.out.println("Chyba");
		}	
		++FileChooser.number;	
*/		
	}	

}