package representation;

import ij.ImagePlus;
import ij.gui.NewImage;
import ij.process.ImageProcessor;

import java.awt.Color;
import java.awt.Image;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageProducer;
import java.awt.image.ReplicateScaleFilter;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Random;
import java.util.Arrays;

import GUI.FileChooser;
import GUI.Result;
import GUI.internalFrame;
import GUI.mainWindow;

public class Moore {
	
	ImagePlus imp;
	ImagePlus imp2;
	//ImagePlus imp3, impSepChar, impSepAll, impOtsu;
	ImagePlus imp3, impSepChar, impSepAll;
	//ImageProcessor ip, nipOtsu;
	ImageProcessor ip;
	ImageProcessor nip, nipSepChar, ipSepAll;
	ImageProcessor nip2;
	ArrayList<ArrayList> contoursI = new ArrayList<ArrayList>();
	ArrayList<ArrayList> contoursJ = new ArrayList<ArrayList>();
	int numberResult;
	boolean draw;
	ReplicateScaleFilter repScale;
	
	int start_i = 0;//punctul de inceput
	int start_j = 0;//punctul de inceput
	
    int prev_start_i = 0;//punctul de inceput
    int prev_start_j = 0;//punctul de inceput
    
    int prev_i = 0;
    int prev_j = 0;
    
    int p_i = 0;//punctul curent
    int p_j = 0;//punctul curent
	
	
	class chainCodeRepr{
		ArrayList x;
		ArrayList y;
		Random random = new Random();
		Color randomColor = Color.getHSBColor( random.nextFloat(), 1.0F, 1.0F );
	}
	
	public Moore(ImagePlus impOtsu, ImagePlus imp, ImageProcessor ip, int numberResult, boolean draw) {
		this.imp = imp;
		this.ip = ip;
		this.numberResult = numberResult;
		this.draw = draw;
		//this.impOtsu =impOtsu;
		//nipOtsu = impOtsu.getProcessor();
	}
	
	private void findAllNeighbours(int i, int j, ImageProcessor nip2){
		if (i != 0)
			if ((nip2.getPixelValue(j, i-1)) == 0) {
				nip2.putPixelValue(j, i-1, 255);
				findAllNeighbours(i-1, j, nip2);
			}
		if ((i!=0) && (j!= nip2.getWidth() -1))
			if ((nip2.getPixelValue(j+1, i-1)) == 0) {
				nip2.putPixelValue(j+1, i-1, 255);
				findAllNeighbours(i-1, j+1, nip2); 
			}
		if (j!= nip2.getWidth() -1)
			if ((nip2.getPixelValue(j+1, i)) == 0) {
				nip2.putPixelValue(j+1, i, 255);
				findAllNeighbours(i, j+1, nip2);
			}
		if ((i!=nip2.getHeight() -1) && (j!= nip2.getWidth() -1))
			if ((nip2.getPixelValue(j+1, i+1)) == 0) {
				nip2.putPixelValue(j+1, i+1, 255);
				findAllNeighbours(i+1, j+1, nip2);
			}
		if (i!=nip2.getHeight() -1)
			if ((nip2.getPixelValue(j, i+1)) == 0) {
				nip2.putPixelValue(j, i+1, 255);
				findAllNeighbours(i+1, j, nip2);
			}
		if ((i!=nip2.getHeight() -1) && (j!= 0))
			if ((nip2.getPixelValue(j-1, i+1)) == 0) {
				nip2.putPixelValue(j-1, i+1, 255);
				findAllNeighbours(i+1, j-1, nip2);
			}
		if (j!=0)
			if ((nip2.getPixelValue(j-1, i)) == 0) {
				nip2.putPixelValue(j-1, i, 255);
				findAllNeighbours(i, j-1, nip2);
			}
		if ((i!=0) && (j!=0))
			if ((nip2.getPixelValue(j-1, i-1)) == 0) {
				nip2.putPixelValue(j-1, i-1, 255);
				findAllNeighbours(i-1, j-1, nip2);
			}
		nip2.putPixelValue(j, i, 255);
	}
	
    
    /**ne deplasam prin matrice in jurul punctului p, incepand de la punctul prev */
    private void deplasare(ImageProcessor nip)//Point p,Point prev)
    {
    	//nip2.getPixelValue(j, i)
    	//j == nip2.getWidth()   x
    	//i == height            y
        int t[]=new int[8];
        int start=0,k=0;
       // System.out.println(p_j+" "+p_i);
        if(p_j==0 && p_i!=0 && (p_i!=nip.getHeight() -1) )
        {
        //	System.out.println("1");
            t[0]=t[6]=t[7]=255;
            t[1]=(int)(nip.getPixelValue(p_j, p_i-1));// canvas.m1[p.x][p.y-1];
            t[2]=(int)(nip.getPixelValue(p_j+1, p_i-1));//canvas.m1[p.x+1][p.y-1];
            t[3]=(int)(nip.getPixelValue(p_j+1, p_i));//canvas.m1[p.x+1][p.y];
            t[4]=(int)(nip.getPixelValue(p_j+1, p_i+1));//canvas.m1[p.x+1][p.y+1];
            t[5]=(int)(nip.getPixelValue(p_j, p_i+1));//canvas.m1[p.x][p.y+1];
        }
        else if( (p_j==nip.getWidth()-1) && p_i!=0 && (p_i!=nip.getHeight()-1) )
        {
        	//System.out.println("2");
            t[2]=t[3]=t[4]=255;
            t[0]=(int)(nip.getPixelValue(p_j-1, p_i-1));//canvas.m1[p.x-1][p.y-1];
            t[1]=(int)(nip.getPixelValue(p_j, p_i-1));//canvas.m1[p.x][p.y-1];
            t[5]=(int)(nip.getPixelValue(p_j, p_i+1));//canvas.m1[p.x][p.y+1];
            t[6]=(int)(nip.getPixelValue(p_j-1, p_i+1));//canvas.m1[p.x-1][p.y+1];
            t[7]=(int)(nip.getPixelValue(p_j-1, p_i));//canvas.m1[p.x-1][p.y];
        }
        else if(p_i==0 && p_j!=0 && (p_j!=nip.getWidth()-1) )
        {
        	//System.out.println("3");
            t[0]=t[1]=t[2]=255;
            t[3]=(int)(nip.getPixelValue(p_j+1, p_i));//canvas.m1[p.x+1][p.y];
            t[4]=(int)(nip.getPixelValue(p_j+1, p_i+1));//canvas.m1[p.x+1][p.y+1];
            t[5]=(int)(nip.getPixelValue(p_j, p_i+1));//canvas.m1[p.x][p.y+1];
            t[6]=(int)(nip.getPixelValue(p_j-1, p_i+1));//canvas.m1[p.x-1][p.y+1];
            t[7]=(int)(nip.getPixelValue(p_j-1, p_i));//canvas.m1[p.x-1][p.y];
        }
        else if( (p_i==nip.getHeight()-1) && p_j!=0 && (p_j!=nip.getWidth() -1) )
        {
        	//System.out.println("4");
            t[6]=t[5]=t[4]=255;
            t[0]=(int)(nip.getPixelValue(p_j-1, p_i-1));//canvas.m1[p.x-1][p.y-1];
            t[1]=(int)(nip.getPixelValue(p_j, p_i-1));//canvas.m1[p.x][p.y-1];
            t[2]=(int)(nip.getPixelValue(p_j+1, p_i-1));//canvas.m1[p.x+1][p.y-1];
            t[3]=(int)(nip.getPixelValue(p_j+1, p_i));//canvas.m1[p.x+1][p.y];
            t[7]=(int)(nip.getPixelValue(p_j-1, p_i));//canvas.m1[p.x-1][p.y];
        }
        else if(p_j==0 && p_i==0)
        {
        	//System.out.println("5");
            t[0]=t[6]=t[7]=t[2]=t[1]=255;
            t[3]=(int)(nip.getPixelValue(p_j+1, p_i));//canvas.m1[p.x+1][p.y];
            t[4]=(int)(nip.getPixelValue(p_j+1, p_i+1));//canvas.m1[p.x+1][p.y+1];
            t[5]=(int)(nip.getPixelValue(p_j, p_i+1));//canvas.m1[p.x][p.y+1];
        }
        else if(p_j==0 && (p_i==nip.getHeight()-1) )
        {
        //	System.out.println("6");
            t[0]=t[6]=t[7]=t[5]=t[4]=255;
            t[1]=(int)(nip.getPixelValue(p_j, p_i-1));//canvas.m1[p.x][p.y-1];
            t[2]=(int)(nip.getPixelValue(p_j+1, p_i-1));//canvas.m1[p.x+1][p.y-1];
            t[3]=(int)(nip.getPixelValue(p_j+1, p_i));//canvas.m1[p.x+1][p.y];
        }
        else if( (p_j==nip.getWidth()-1) && p_i==0)
        {
        	//System.out.println("7");
            t[0]=t[1]=t[2]=t[3]=t[4]=255;
            t[5]=(int)(nip.getPixelValue(p_j, p_i+1));//canvas.m1[p.x][p.y+1];
            t[6]=(int)(nip.getPixelValue(p_j-1, p_i+1));//canvas.m1[p.x-1][p.y+1];
            t[7]=(int)(nip.getPixelValue(p_j-1, p_i));//canvas.m1[p.x-1][p.y];
        }
        else if( (p_j==nip.getWidth()-1) && (p_i==nip.getHeight()-1) )
        {
        //	System.out.println("8");
            t[6]=t[5]=t[4]=t[2]=t[3]=255;
            t[0]=(int)(nip.getPixelValue(p_j-1, p_i-1));//canvas.m1[p.x-1][p.y-1];
            t[1]=(int)(nip.getPixelValue(p_j, p_i-1));//canvas.m1[p.x][p.y-1];
            t[7]=(int)(nip.getPixelValue(p_j-1, p_i));//canvas.m1[p.x-1][p.y];
        }
        else{
        	//System.out.println("9");
            t[0]=(int)(nip.getPixelValue(p_j-1, p_i-1));//canvas.m1[p.x-1][p.y-1];
            t[1]=(int)(nip.getPixelValue(p_j, p_i-1));//canvas.m1[p.x][p.y-1];
            t[2]=(int)(nip.getPixelValue(p_j+1, p_i-1));//canvas.m1[p.x+1][p.y-1];
            t[3]=(int)(nip.getPixelValue(p_j+1, p_i));//canvas.m1[p.x+1][p.y];
            t[4]=(int)(nip.getPixelValue(p_j+1, p_i+1));//canvas.m1[p.x+1][p.y+1];
            t[5]=(int)(nip.getPixelValue(p_j, p_i+1));//canvas.m1[p.x][p.y+1];
            t[6]=(int)(nip.getPixelValue(p_j-1, p_i+1));//canvas.m1[p.x-1][p.y+1];
            t[7]=(int)(nip.getPixelValue(p_j-1, p_i));//canvas.m1[p.x-1][p.y];
         //   System.out.println(t[0]+" "+t[1]+" "+t[2]+" "+t[3]+" "+t[4]+" "+t[5]+" "+t[6]+" "+t[7]);
        }
        if( (prev_j==p_j-1) && (prev_i==p_i-1) )start=0;
        if((prev_j==p_j) && (prev_i==p_i-1) )start=1;
        if((prev_j==p_j+1) && (prev_i==p_i-1) )start=2;
        if((prev_j==p_j+1) && (prev_i==p_i) )start=3;
        if((prev_j==p_j+1) && (prev_i==p_i+1) )start=4;
        if((prev_j==p_j) && (prev_i==p_i+1) )start=5;
        if((prev_j==p_j-1) && (prev_i==p_i+1) )start=6;
        if((prev_j==p_j-1) && (prev_i==p_i) )start=7;
        //System.out.println("start "+start);
        for(k=start+1;k<8;k++)
        {
            if(t[k]==0)break;
        }
        if(k==8)for(k=0;k<=start;k++)if(t[k]==0)break;
        /*prev.x=p.x;
        prev.y=p.y;*/
       // System.out.println("k "+k);
        if(k==0)
        {
            prev_j=p_j-1;
            prev_i=p_i;
            p_j=p_j-1;
            p_i=p_i-1;
        } else
        if(k==1)
        {
            prev_j=p_j-1;
            prev_i=p_i-1;
            p_j=p_j;
            p_i=p_i-1;
        }else
        if(k==2)
        {
            prev_j=p_j;
            prev_i=p_i-1;
            p_j=p_j+1;
            p_i=p_i-1;
        }else
        if(k==3)
        {
            prev_j=p_j+1;
            prev_i=p_i-1;
            p_j=p_j+1;
            p_i=p_i;
        }else
        if(k==4)
        {
            prev_j=p_j+1;
            prev_i=p_i;
            p_j=p_j+1;
            p_i=p_i+1;
        }else
        if(k==5)
        {
            prev_j=p_j+1;
            prev_i=p_i+1;
            p_j=p_j;
            p_i=p_i+1;
        }else
        if(k==6)
        {
            prev_j=p_j;
            prev_i=p_i+1;
            p_j=p_j-1;
            p_i=p_i+1;
        }else
        if(k==7)
        {
            prev_j=p_j-1;
            prev_i=p_i+1;
            p_j=p_j-1;
            p_i=p_i;
        }
    }
    
    private boolean emptyImage(ImageProcessor nip){
		for (int i = 0; i < nip.getWidth(); i++) {
			for (int j = 0; j < nip.getHeight(); j++) {			
				if (nip.getPixelValue(i, j) == 0) {
					return false;
				}
			}
		}	    	
		return true;
    }
	
    /**algoritmul MooreNeighbor*/
    public void run(boolean draw2){
		imp2 = NewImage.createRGBImage ("Moore's algorithm", ip.getWidth(), ip.getHeight(), 1, NewImage.FILL_WHITE);
		nip = imp2.getProcessor();	
		
		ImagePlus imp3 = NewImage.createRGBImage ("Moore's algorithm", ip.getWidth(), ip.getHeight(), 1, NewImage.FILL_WHITE);
		ImageProcessor nip2 = imp3.getProcessor();
		
			for (int i = 0; i < ip.getWidth(); i++) {
				for (int j = 0; j < ip.getHeight(); j++) {			
					nip2.putPixel(i, j, ip.getPixel(i, j));
				}
			}
    	        
        int orientare=0;//{0,1,2,3} cu 0 -in sus;1-la dreapta, etc..
        int i,j,dati=0;
        //1 je cierna 
        // 0 je biela
		ArrayList listi = new ArrayList();
		ArrayList listj = new ArrayList();
		Random random = new Random();
		Color randomColor = Color.getHSBColor( random.nextFloat(), 1.0F, 1.0F );
		int color = 0;
		ArrayList contI = new ArrayList();
		ArrayList contJ = new ArrayList();
		
		//int pocitam = 0;
		while (emptyImage(nip2) == false) {
			
/*			pocitam++;
			if (pocitam > 500)
				System.out.println("ZASEKAVAM SA?? MOORE");*/
			
	        for(i=0;i<ip.getWidth();i++)
	        {
	            for(j = ip.getHeight()-1; j>=0 ;j--) 
	                if (nip2.getPixelValue(i, j) == 0)//if(canvas.m1[i][j]==1)
	                {
	                    prev_start_j=prev_j=i;
	                    prev_start_i=prev_i=j+1;
	                    start_j=p_j=i;
	                    p_i=start_i=j;

	                    listi.add(i);
	                    listj.add(j);
	            		contI = new ArrayList();
	            		contJ = new ArrayList();
	                    
	                    contI.add(j);
	                    contJ.add(i);
	                    
//	                    System.out.println("i "+i);
//	                    System.out.println("j "+j);
	        			randomColor = Color.getHSBColor( random.nextFloat(), 1.0F, 1.0F );
	        			color = ((randomColor.getRed() & 0xff) << 16) + ((randomColor.getGreen() & 0xff) << 8) + (randomColor.getBlue() & 0xff);
	        			
	                    nip.putPixel(i, j, color);//canvas.m2[i][j]=1;
	                    break;
	                }
	            if(j>=0)break;
	        }
	        /**cautam marginea desenului pana nu am ajuns in punctul de start din acelasi predecesor*/
	        int pocet = 0;
	        do{
	        	//System.out.println("ZASEKAVAM SA??moore do");
	        	pocet++;
	        	if (pocet > 200)
	        		break;
	        	deplasare(nip2);
	            //System.out.println("new "+p_j+" "+p_i+"\t"+prev_j+" "+prev_i);
	            nip.putPixel(p_j, p_i, color);//canvas.m2[p.x][p.y]=1;
                contI.add(p_i);
                contJ.add(p_j);

	        }while(p_j!=start_j || p_i!=start_i || prev_j!=prev_start_j || prev_i!=prev_start_i);
	        
	    //    System.out.println("pred find");
			for (int k = 0; k < listi.size(); k++) {
				findAllNeighbours((Integer)(listj.get(k)), (Integer)(listi.get(k)), nip2);
			}
			contoursI.add(contI);
			contoursJ.add(contJ);
			
	    }
		
			        
/*		while (emptyImage(nip2) == false) {
	  // for(int l=0;l<5;l++) {
			for(i=0;i<ip.getHeight();i++)
	        {
	            //for(j = ip.getHeight()-1; j>=0 ;j--) 
	            for(j = ip.getWidth()-1; j>=0 ;j--)
	                if (nip2.getPixelValue(j, i) == 0)//if(canvas.m1[i][j]==1)
	                {
	                    prev_start_j=prev_j=j+1;
	                    prev_start_i=prev_i=i;
	                    start_j=p_j=j;
	                    p_i=start_i=i;

	                    listi.add(j);
	                    listj.add(i);
	            		contI = new ArrayList();
	            		contJ = new ArrayList();
	                    
	                    contI.add(j);
	                    contJ.add(i);
//	                    System.out.println("i "+i);
//	                    System.out.println("j "+j);
	        			randomColor = Color.getHSBColor( random.nextFloat(), 1.0F, 1.0F );
	        			color = ((randomColor.getRed() & 0xff) << 16) + ((randomColor.getGreen() & 0xff) << 8) + (randomColor.getBlue() & 0xff);
	        			
	                    nip.putPixel(j, i, color);//canvas.m2[i][j]=1;
	                    break;
	                }
	            if(j>=0)break;
	        }
	        *//**cautam marginea desenului pana nu am ajuns in punctul de start din acelasi predecesor*//*
	        int pocet = 0;
	        do{
	        	pocet++;
	        	if (pocet > 200)
	        		break;
	        	deplasare(nip2);
	            //System.out.println("new "+p_j+" "+p_i+"\t"+prev_j+" "+prev_i);
	            nip.putPixel(p_j, p_i, color);//canvas.m2[p.x][p.y]=1;
                contI.add(p_j);
                contJ.add(p_i);

	        }while(p_j!=start_j || p_i!=start_i || prev_j!=prev_start_j || prev_i!=prev_start_i);
	        
	    //    System.out.println("pred find");
			for (int k = 0; k < listi.size(); k++) {
				findAllNeighbours((Integer)(listj.get(k)), (Integer)(listi.get(k)), nip2);
			}
			contoursI.add(contI);
			contoursJ.add(contJ);
			
	    }
*/		//nip
		if (draw2) {
			mainWindow.intFrameArrayList.add(new internalFrame("Moore's algorithm", imp2, 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;
		}
		
/*			//nip
		mainWindow.intFrame[FileChooser.number] = new internalFrame("Moore's algorithm", imp3, FileChooser.number, numberResult, true);
		try {
			mainWindow.intFrame[FileChooser.number].setSelected(true);
		} catch(Exception e){
			System.out.println("Chyba");
		}	
		++FileChooser.number;
*/		
		
		System.runFinalization();
		System.gc();
			
}

	public ImageProcessor separateGrapheme(ImageProcessor ip){
				
		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
		
		ArrayList redIlines = new ArrayList();
		
		for (int j = 0; j < ip.getHeight(); j++) {			
			if (ip.getPixel(0, j) == color) {
				redIlines.add(j);
			//	System.out.println("redIlines "+redIlines.get(redIlines.size()-1));
			}
		}
		
		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-1, j) != color) && (ip.getPixel(i-1, j) != color2))){
						int index = -1;
						//System.out.println("i j "+i+" "+j);
						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;
							//System.out.println("(Integer)(redIbottom.get(k)) "+(Integer)(redIbottom.get(k)));
							//System.out.println("(Integer)(redIlines.get(index)) "+(Integer)(redIlines.get(index)));
							//if ((index >= 0) && (index < redIlines.size()))
							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 == -1);
							else 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++) {	
			//redItop.add(redItop.get(redItop.size() -1 - i - i));
			//redIbottom.add(redIbottom.get(redIbottom.size() -1 - i - i));
			if (i == 0)
				redItop.add(0);
			else 
				redItop.add((Integer)(redIlines.get(i-1)));
			redIbottom.add((Integer)(redIlines.get(i)));
			
			int maxRight = 0;
			for (int j = 0; j < redJright.size(); j++) {
				if ( ( (Integer)(redItop.get(j)) == (Integer)(redItop.get(redItop.size() - 1))) && ( (Integer)(redIbottom.get(j)) == (Integer)(redIbottom.get(redIbottom.size()-1))) )
					if  ( (Integer)(redJright.get(j)) > maxRight )
						maxRight = (Integer)(redJright.get(j));
			}
			
			redJleft.add(maxRight);
			redJright.add(ip.getWidth());//redJright.add(ip.getWidth());
			
		//	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));

		}
		
		System.out.println();
		
		//for (int i = 0; i < redIbottom.size(); i++) {
			//if ( (Integer)(redItop.get(i)) == 50)
			//	System.out.println("top "+redItop.get(i)+" bottom "+ redIbottom.get(i)+" left "+ redJleft.get(i)+" right "+redJright.get(i));
		//}
		
		impSepAll = NewImage.createRGBImage ("Graphemes Separation", ip.getWidth(), ip.getHeight(), 1, NewImage.FILL_WHITE);
		ipSepAll = impSepAll.getProcessor();	
		
		ImagePlus imp4 = NewImage.createRGBImage ("Graphemes Separation", ip.getWidth(), ip.getHeight(), 1, NewImage.FILL_WHITE);
		ImageProcessor nip3 = imp4.getProcessor();	
		
		for (int i = 0; i < ip.getWidth(); i++) {
			for (int j = 0; j < ip.getHeight(); j++) {			
				ipSepAll.putPixel(i, j, ip.getPixel(i, j));
			}
		}
		
		for (int q = 0; q < redJright.size(); q++) {

		//begin
			
					ArrayList<ArrayList> lowerContoursI = new ArrayList<ArrayList>();
					ArrayList<ArrayList> lowerContoursJ = new ArrayList<ArrayList>();
					
					ArrayList<ArrayList> upperContoursI = new ArrayList<ArrayList>();
					ArrayList<ArrayList> upperContoursJ = new ArrayList<ArrayList>();	
					
					ArrayList<ArrayList> newContoursI = new ArrayList<ArrayList>();
					ArrayList<ArrayList> newContoursJ = new ArrayList<ArrayList>();	
					
					for (int i = 0; i < contoursJ.size(); i++) {
						ArrayList newConI = new ArrayList();
						ArrayList newConJ = new ArrayList();
						for (int j = 0; j < contoursI.get(i).size(); j++) {
							if ( ( (Integer)(redIbottom.get(q)) > (Integer)(contoursI.get(i).get(j)) ) &&
								( (Integer)(redItop.get(q)) < (Integer)(contoursI.get(i).get(j)) )  &&
							    ( (Integer)(redJleft.get(q)) < (Integer)(contoursJ.get(i).get(j)) ) &&
							    ( (Integer)(redJright.get(q)) > (Integer)(contoursJ.get(i).get(j)) ) ) {
								newConI.add((Integer)(contoursI.get(i).get(j)));
								newConJ.add((Integer)(contoursJ.get(i).get(j)));
							}
								
						}
						if (!newConI.isEmpty()) {
							newContoursI.add(newConI);
							newContoursJ.add(newConJ);
						}
					}
					
					//for (int i = 0; i < newContoursI.size(); i++) {
						//for (int j = 0; j < newContoursI.get(i).size(); j++) {
							//System.out.println("newCon I, J"+" "+i+" "+j+ ": "+newContoursI.get(i).get(j)+", "+newContoursJ.get(i).get(j));
						//}
					//}
					
					//////////
					int[][] sortJ = new int[newContoursJ.size()][];
					int[][] noSortJ = new int[newContoursJ.size()][];
					int[][] sortI = new int[newContoursI.size()][];
					int[][] noSortI = new int[newContoursI.size()][];
					
					for (int i = 0; i < newContoursJ.size(); i++) {
						sortJ[i] = new int[newContoursJ.get(i).size()];
						sortI[i] = new int[newContoursI.get(i).size()];
						noSortJ[i] = new int[newContoursJ.get(i).size()];
						noSortI[i] = new int[newContoursI.get(i).size()];
						for (int j = 0; j < newContoursJ.get(i).size(); j++) {
							sortJ[i][j] = (Integer)(newContoursJ.get(i).get(j));
							sortI[i][j] = (Integer)(newContoursI.get(i).get(j));
							noSortJ[i][j] = (Integer)(newContoursJ.get(i).get(j));
							noSortI[i][j] = (Integer)(newContoursI.get(i).get(j));
						}
					}
					
					for (int i = 0; i < sortJ.length; i++) {
						Arrays.sort(sortJ[i]);
					}
					
					for (int i = 0; i < sortJ.length; i++) {
						for (int j = 0; j < sortJ[i].length; j++) {
					
						//	for (int k = 0; k < noSortJ.length; k++) {
								boolean find = false;
								for (int l = 0; l < noSortJ[i].length; l++) {
									if ((sortJ[i][j] == noSortJ[i][l]) && (!find)) {
										if (noSortI[i][l] != -1) {
											sortI[i][j] = noSortI[i][l];
											noSortI[i][l] = -1;
											find = true;
										}
									}
								}
						//	}
							
						}
					}
					/////////////
					
					for (int i = 0; i < newContoursJ.size(); i++) {
						ArrayList upperI = new ArrayList();
						ArrayList upperJ = new ArrayList();
						ArrayList lowerI = new ArrayList();
						ArrayList lowerJ = new ArrayList();
						
						int minI = sortI[i][0];
						int maxI = sortI[i][sortI[i].length -1];
						for (int j = 0; j <  sortI[i].length; j++) {
							if (sortJ[i][j] == sortJ[i][0])
								if (sortI[i][j] < minI) minI = sortI[i][j];
							if (sortJ[i][j] == sortJ[i][sortJ[i].length -1])
								if (sortI[i][j] < maxI) maxI = sortI[i][j];
						}
			
						upperI.add(minI);
						upperJ.add(sortJ[i][0]);
						lowerI.add(maxI);
						lowerJ.add(sortJ[i][sortJ[i].length -1]);
					//	System.out.println("minI "+minI);
						//System.out.println("sortJ[i][0] "+sortJ[i][0]);
					//	System.out.println("maxI "+maxI);
					//	System.out.println("sortJ[i][sortJ[i].length -1] "+sortJ[i][sortJ[i].length -1]);
						int stav = -1; //-1hlada zaciatok, 0 - nasiel zaciatok 1 - nasiel koniec
						int j = 0;
						int count = 0;
						while ((stav != 1) && (count <500)){
/*							if (count > 500)
								System.out.println("ZASEKAVAM SA??moore");*/
					//	for (int j = 0; j <  contoursJ.get(i).size(); j++) {
							if (( (Integer)(newContoursJ.get(i).get(j)) == sortJ[i][sortJ[i].length -1] ) && ( (Integer)(newContoursI.get(i).get(j)) == maxI))
								if (stav == 0)
									stav = 1;
							if (( (Integer)(newContoursJ.get(i).get(j)) == sortJ[i][0] ) && ( (Integer)(newContoursI.get(i).get(j)) == minI))
								stav = 0;
							if (stav == 0)
									if ( Math.abs((Integer)(upperI.get(upperI.size() - 1)) - (Integer)(newContoursI.get(i).get(j))) <= 1) {
										upperI.add((Integer)(newContoursI.get(i).get(j)));
										upperJ.add((Integer)(newContoursJ.get(i).get(j)));
									//	System.out.println("upperI.get(upperI.size() -1) "+upperI.get(upperI.size() -1));
									//	System.out.println("upperJ.get(upperJ.size() -1) "+upperJ.get(upperJ.size() -1));
									}
							if (j == newContoursJ.get(i).size() -1) j = 0;
							else j++;
						//	System.out.println("stav "+stav);
							count++;
						//	System.out.println("count "+count);
						}
						stav = -1;
						count = 0;
			//			-1hlada koniec, 0 - nasiel koniec 1 - nasiel zaciatok
						while (( stav != 1) && (count <500)){
	/*						if (count > 500)
							System.out.println("ZASEKAVAM SA??moore");*/
							//	for (int j = 0; j <  newContoursJ.get(i).size(); j++) {
									if (( (Integer)(newContoursJ.get(i).get(j)) == sortJ[i][sortJ[i].length -1] ) && ( (Integer)(newContoursI.get(i).get(j)) == maxI))
											stav = 0;
									if (( (Integer)(newContoursJ.get(i).get(j)) == sortJ[i][0] ) && ( (Integer)(newContoursI.get(i).get(j)) == minI))
										if (stav == 0)
											stav = 1;
									if (stav == 0)
											if ( Math.abs((Integer)(lowerI.get(lowerI.size() - 1)) - (Integer)(newContoursI.get(i).get(j))) <= 1) {
												lowerI.add((Integer)(newContoursI.get(i).get(j)));
												lowerJ.add((Integer)(newContoursJ.get(i).get(j)));
											}
									if (j == newContoursJ.get(i).size() -1) j = 0;
									else j++;
									//System.out.println("stav "+stav);
									count++;
						}
						upperContoursJ.add(upperJ);
						upperContoursI.add(upperI);
						lowerContoursJ.add(lowerJ);
						lowerContoursI.add(lowerI);
					}		
					
					ArrayList<ArrayList> differenceI = new ArrayList<ArrayList>();
					
					for (int i = 0; i < lowerContoursJ.size(); i++) {
						ArrayList difI = new ArrayList();
			
						for (int j = 0; j < lowerContoursJ.get(i).size(); j++) {
							
							int countLower = 0;
							for (int b = 0; b < lowerContoursJ.size(); b++) {
								for (int k = 0; k < lowerContoursJ.get(b).size(); k++) {
									int l = (Integer)(lowerContoursJ.get(i).get(j));
									int u = (Integer)(lowerContoursJ.get(b).get(k));
									if ((k != j) && (i != b))
										if (l == u)
											countLower++;
								}
							}
							//int dif = 0;
							//System.out.println("new");
							int uI = 0;
							int lI = 0;
							int count = 0;
							for (int f = 0; f < upperContoursJ.size(); f++) {
								for (int index = 0; index < upperContoursJ.get(f).size(); index++) {
									int l = (Integer)(lowerContoursJ.get(i).get(j));
									int u = (Integer)(upperContoursJ.get(f).get(index));
									if (l == u) {
										count++;
										uI = (Integer)(upperContoursI.get(f).get(index));
										lI = (Integer)(lowerContoursI.get(i).get(j));
										//System.out.println("uI "+uI);
/*										if ((dif < uI) && (uI < lI))
											dif = uI;*/
									}
								}
						     }
							//	System.out.println("lI "+lI);
							//	System.out.println("uI "+uI);
								if (countLower == 0)
									difI.add(lI - uI);
								else 
									difI.add(40);
								//difI.add(dif);
						}
						differenceI.add(difI);
					}
					
/*					for (int i = 0; i < lowerContoursJ.size(); i++) {
						ArrayList difI = new ArrayList();
			
						for (int j = 0; j < lowerContoursJ.get(i).size(); j++) {
			
							int dif = 0;
							//System.out.println("new");
								for (int index = 0; index < upperContoursJ.get(i).size(); index++) {
									int l = (Integer)(lowerContoursJ.get(i).get(j));
									int u = (Integer)(upperContoursJ.get(i).get(index));
									if (l == u) {
										int uI = (Integer)(upperContoursI.get(i).get(index));
										int lI = (Integer)(lowerContoursI.get(i).get(j));
										//System.out.println("uI "+uI);
										if ((dif < uI) && (uI < lI))
											dif = uI;
									}
								}
								int lI = (Integer)(lowerContoursI.get(i).get(j));
								//System.out.println("lI "+lI);
								//System.out.println("dif "+dif);
								difI.add(lI - dif);
								//difI.add(dif);
						}
						differenceI.add(difI);
					}*/
					
					int[][] sortDif = new int[differenceI.size()][];
					for (int i = 0; i < differenceI.size(); i++) {
						sortDif[i] = new int[differenceI.get(i).size()];
						for (int j = 0; j < differenceI.get(i).size(); j++) {
							sortDif[i][j] = (Integer)(differenceI.get(i).get(j));
						}
					}
					
					for (int i = 0; i < sortDif.length; i++) {
						Arrays.sort(sortDif[i]);
					}
					
					int sum =0;
					int count = 0;
					for (int i = 0; i < sortDif.length; i++) {
						for (int j = 0; j < sortDif[i].length; j++) {
							sum = sum + sortDif[i][j];
							count++;
						}
					}
					//sum = sum / count;
				//	System.out.println("sum "+sum);
					
					//for (int i = 0; i < sortDif.length; i++) {
						//for (int j = 0; j < sortDif[i].length; j++) {
							//System.out.println("sortDif[i][j] "+sortDif[i][j]);
						//}
				    //}
					
					ArrayList sortDif2 = new ArrayList();
					for (int i = 0; i < sortDif.length; i++) {
						for (int j = 0; j < sortDif[i].length; j++) {
							if (j == 0)
								sortDif2.add(sortDif[i][j]);
							else {
								if ((Integer)(sortDif2.get(sortDif2.size() -1)) != sortDif[i][j])
									sortDif2.add(sortDif[i][j]);
							}
						}
					}
					
					//for (int i = 0; i < sortDif2.size(); i++) {
							//System.out.println("sortDif2[i][j] "+sortDif2.get(i));
					//}
					int maxDif = 0;
					if (sortDif2.size() != 0)
						maxDif = (Integer)(sortDif2.get(sortDif2.size() / 5));
					
					maxDif = 20;
				//	System.out.println("maxDif "+maxDif);
			/*		for (int i = 0; i < lowerContoursJ.size(); i++) {
						ArrayList difI = new ArrayList();
						for (int m = 0; m < lowerContoursJ.get(i).size(); m++) {
						
						//	for (int k = 0; k < sortJ.length; k++) {					
								int dif = (Integer)(lowerContoursI.get(i).get(m));
								for (int j = 0; j < sortJ[i].length; j++) {
									
									if ((Integer)(lowerContoursJ.get(i).get(m)) == sortJ[i][j])
										if ((((Integer)(lowerContoursI.get(i).get(m)) - sortI[i][j]) < dif) && (((Integer)(lowerContoursI.get(i).get(m)) - sortI[i][j]) >0))
											dif = sortI[i][j];//(Integer)(lowerContoursI.get(i).get(m));
								}
							//}
								difI.add(dif);
						}
						differenceI.add(difI);
					}*/
					
			
					ArrayList<ArrayList> info = new ArrayList<ArrayList>();
					for (int i = 0; i < lowerContoursI.size(); i++) {
			
						ArrayList inf = new ArrayList();
						for (int j = 0; j < lowerContoursI.get(i).size(); j++) {
						//	System.out.println("lowerContoursI.get(i).get(j) "+lowerContoursI.get(i).get(j));
							if (j == 0) {
							//	mI.add((Integer)(contoursI.get(i).get(j)));
							//	mJ.add((Integer)(contoursJ.get(i).get(j)));
								inf.add("rovno");
								//System.out.println("rovno");
							} else {
								int j1 = (Integer)(lowerContoursI.get(i).get(j-1));
								int j2 = (Integer)(lowerContoursI.get(i).get(j));
							//	System.out.println("lowerContoursI.get(i).get(j-1) "+j1);
							//	System.out.println("lowerContoursI.get(i).get(j) "+j2);
							//	if ((Integer)(lowerContoursJ.get(i).get(j)) != (Integer)(lowerContoursJ.get(i).get(j -1)) )
								if (j2 > j1 ) {
								//	System.out.println("((Integer)(lowerContoursI.get(i).get(j))) "+((Integer)(lowerContoursI.get(i).get(j))));
								//	System.out.println("((Integer)(lowerContoursI.get(i).get(j-1))) "+((Integer)(lowerContoursI.get(i).get(j-1))));
								//	System.out.println("klesa");
									inf.add("klesa");
								}else if (j2 == j1) {
								//	System.out.println("((Integer)(lowerContoursI.get(i).get(j))) "+((Integer)(lowerContoursI.get(i).get(j))));
								//	System.out.println("((Integer)(lowerContoursI.get(i).get(j-1))) "+((Integer)(lowerContoursI.get(i).get(j-1))));
									
									inf.add("rovno");
								//	System.out.println("rovno");
								} else if (j2 < j1) {
								//	System.out.println("((Integer)(lowerContoursI.get(i).get(j))) "+((Integer)(lowerContoursI.get(i).get(j))));
								//	System.out.println("((Integer)(lowerContoursI.get(i).get(j-1))) "+((Integer)(lowerContoursI.get(i).get(j-1))));
			
									inf.add("stupa");
								//	System.out.println("stupa");
								}	
							}
						}
						info.add(inf);
					}
			
			/*		for (int i = 0; i < info.size(); i++) {
						for (int j = 0; j < info.get(i).size(); j++) {
							System.out.println("info "+info.get(i).get(j));
						}
					}*/
					
					int min = -1; //-1 nic, 0 - klesa, 1 - rovno, 2 - stupa
					int mI = 0, mJ = 0;
					ArrayList minI = new ArrayList();
					ArrayList minJ = new ArrayList();
					for (int i = 0; i < info.size(); i++) {
						for (int j = 0; j < info.get(i).size(); j++) {
							String in = (String)(info.get(i).get(j));
							if ( ((min == -1) || (min == 0)) && ((in).compareTo("klesa") == 0)) {
								min = 0;
							//	System.out.println("(Integer)(differenceI.get(i).get(j)) "+(Integer)(differenceI.get(i).get(j)));
/*								if ((Integer)(differenceI.get(i).get(j)) < maxDif) {
									mI = (Integer)(lowerContoursI.get(i).get(j));
									mJ = (Integer)(lowerContoursJ.get(i).get(j));
								} else {
									mI = -1;
								}*/
							} else if ( ((min == -1) || (min == 0) || (min == 1)) && ((in).compareTo("rovno") == 0)) {
								min = 1;
								//System.out.println("(Integer)(differenceI.get(i).get(j)) "+(Integer)(differenceI.get(i).get(j)));
								if ((Integer)(differenceI.get(i).get(j)) < maxDif) {
									mI = (Integer)(lowerContoursI.get(i).get(j));
									mJ = (Integer)(lowerContoursJ.get(i).get(j));
								} else {
									mI = -1;
								}
							} else if ( ((min == 0) || (min == 1) || (min == 2) ) && ((in).compareTo("stupa") == 0)) {
								min = 2;
								if (!minJ.isEmpty()){
									int m = (Integer)(minJ.get(minJ.size() -1));
									if ( ( m != mJ) && (mI != -1) ) {
										boolean ok = true;
/*										for (int k = 0; k < redJleft.size(); k++) {
											if (Math.abs((Integer)redJleft.get(k) - mJ) <= 5)
												ok = false;
										}
										for (int k = 0; k < redJright.size(); k++) {
											if (Math.abs((Integer)redJright.get(k) - mJ) <= 5)
												ok = false;
										}*/
									//	for (int k = 0; k < redJleft.size(); k++) {
			/*								if ( ( (Integer)(redIbottom.get(q)) >= mI) &&
												( (Integer)(redItop.get(q)) <= mI )  &&
											    ( (Integer)(redJleft.get(q)) <= mJ ) &&
											    ( (Integer)(redJright.get(q)) >= mJ ) ) {*/
										//System.out.println("(Integer)redJright.get(q) "+(Integer)redJright.get(q));
										//System.out.println("(Integer)redJleft.get(q) "+(Integer)redJleft.get(q));
										//System.out.println("mJ "+mJ);
													if (Math.abs((Integer)redJright.get(q) - mJ) <= 10) {
														ok = false;
														//System.out.println("Math.abs((Integer)redJright.get(q) - mJ) "+Math.abs((Integer)redJright.get(q) - mJ));
													} 
													if (Math.abs((Integer)redJleft.get(q) - mJ) <= 10) {
														//System.out.println("Math.abs((Integer)redJleft.get(q) - mJ) "+Math.abs((Integer)redJleft.get(q) - mJ));
														ok = false;
													}
											// }
									//	}
										
										if (( Math.abs(m - mJ) >10) && (ok) ) {
											minI.add(mI);
											minJ.add(mJ);
										}
									//	System.out.println("add");
									//	System.out.println("minI "+mI);System.out.println("minJ "+mJ);
									}
								} else {
									if (mI != -1) {
										boolean ok = true;
										//System.out.println("(Integer)redJright.get(q) "+(Integer)redJright.get(q));
										//System.out.println("(Integer)redJleft.get(q) "+(Integer)redJleft.get(q));
										//System.out.println("mJ "+mJ);
										if (Math.abs((Integer)redJright.get(q) - mJ) <= 10) {
											ok = false;
											//System.out.println("Math.abs((Integer)redJright.get(q) - mJ) "+Math.abs((Integer)redJright.get(q) - mJ));
										} 
										if (Math.abs((Integer)redJleft.get(q) - mJ) <= 10) {
											//System.out.println("Math.abs((Integer)redJleft.get(q) - mJ) "+Math.abs((Integer)redJleft.get(q) - mJ));
											ok = false;
										}
										if (ok) {
											minI.add(mI);
											minJ.add(mJ);
										}
									}
									//System.out.println("add");
									//System.out.println("minI "+mI);System.out.println("minJ "+mJ);
								}
							} else 
								if ((in).compareTo("klesa") == 0) min = 0;
								else min = -1;
							//System.out.println("min "+min);
							//System.out.println("((String)(info.get(i).get(j))) "+((String)(info.get(i).get(j))));
							//System.out.println("((Integer)(lowerContoursJ.get(i).get(j))) "+((Integer)(lowerContoursJ.get(i).get(j))));
							//System.out.println("((Integer)(lowerContoursI.get(i).get(j))) "+((Integer)(lowerContoursI.get(i).get(j))));
						}
					}
					
			
					color = ((Color.red.getRed() & 0xff) << 16) + ((0 & 0xff) << 8) + (0 & 0xff);
					nip3.setColor(color);
					
					for (int i = 0; i < upperContoursJ.size(); i++) {
						for (int j = 0; j < upperContoursJ.get(i).size(); j++) {
							nip3.putPixel((Integer)(upperContoursJ.get(i).get(j)), (Integer)(upperContoursI.get(i).get(j)), color);
							//nip2.putPixel((Integer)(lowerContoursJ.get(i).get(j)), (Integer)(differenceI.get(i).get(j)), color);
						}
					}
					
					color = ((0 & 0xff) << 16) + ((0 & 0xff) << 8) + (Color.blue.getBlue() & 0xff);
					ipSepAll.setColor(color);
					for (int i = 0; i < lowerContoursJ.size(); i++) {
						for (int j = 0; j < lowerContoursJ.get(i).size(); j++) {
							nip3.putPixel((Integer)(lowerContoursJ.get(i).get(j)), (Integer)(lowerContoursI.get(i).get(j)), color);
						}
					}	
					
					//color = ((Color.red.getRed() & 0xff) << 16) + ((0 & 0xff) << 8) + (0 & 0xff);
					color = ((0 & 0xff) << 16) + ((Color.green.getGreen() & 0xff) << 8) + (0 & 0xff);
					ipSepAll.setColor(color);
					
					for (int i = 0; i < minJ.size(); i++) {
						ipSepAll.drawLine((Integer)(minJ.get(i)), (Integer)(redItop.get(q)), (Integer)(minJ.get(i)), (Integer)(redIbottom.get(q)));//(Integer)(minI.get(i)));//(Integer)(redIbottom.get(q)));
			
					}
					
		//end
					
		}
		
		if (draw) {
			//nip3
			mainWindow.intFrameArrayList.add(new internalFrame("Lower and Upper contours", imp4, 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;
			
			//nip2
			mainWindow.intFrameArrayList.add(new internalFrame("Grapheme segmentation", impSepAll, 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;			
			
		}
		
		System.runFinalization();
		System.gc();
		
		return ipSepAll;
	}

	
	////////////////WORDS///////////////////////////////WORDS///////////////WORDS/////////////////////////
	public ImageProcessor separateWords(boolean kresliModre, boolean draw3){
		
		int color = ((Color.red.getRed() & 0xff) << 16) + ((0 & 0xff) << 8) + (0 & 0xff); //red color
		
		ArrayList redJ = new ArrayList();
		//ip = nipOtsu;
		
			for (int j = 0; j < ip.getHeight(); j++) {			
				if (ip.getPixel(0, j) == color) {
					redJ.add(j);
					//System.out.println("red "+j);
				}
			}
		
	//	int[] min = new int[contoursJ.size()]; //width
	//	int[] max = new int[contoursJ.size()]; //width
		
		ArrayList<ArrayList> min = new ArrayList<ArrayList>();
		ArrayList<ArrayList> max = new ArrayList<ArrayList>();
		
		//ArrayList<ArrayList> resultMaxHeight = new ArrayList<ArrayList>(); //maximalna vyska pisma
	//	ArrayList<ArrayList> resultAverHeight = new ArrayList<ArrayList>();//priemerna vyska pisma
		
		for (int k = 0; k < redJ.size(); k++) {
			ArrayList min1 = new ArrayList();
			ArrayList max1 = new ArrayList();
			
		//	ArrayList resMaxHeight = new ArrayList();
		//	ArrayList resAverHeight = new ArrayList();
			
			for (int i = 0; i < contoursJ.size(); i++) {
				
				if (k == 0) {
					if ( (Integer)(contoursI.get(i).get(0)) < (Integer)(redJ.get(k)) )  {

						min1.add((Integer)(contoursJ.get(i).get(0)));
						max1.add((Integer)(contoursJ.get(i).get(0)));
						
					//	resAverHeight.add((Integer)(contoursI.get(i).get(0)));
					//	resMaxHeight.add((Integer)(contoursI.get(i).get(0)));
						
						for (int j = 0; j < contoursJ.get(i).size(); j++) {
							if ( (Integer)(contoursJ.get(i).get(j)) < (Integer)(min1.get(min1.size() -1)) ) {
								min1.remove(min1.size() -1);
								min1.add((Integer)(contoursJ.get(i).get(j)));
								//System.out.println("add min1 "+(min1.size() -1)+" "+(Integer)(contoursJ.get(i).get(j)));
							}
							if ( (Integer)(contoursJ.get(i).get(j)) > (Integer)(max1.get(max1.size() -1)) ) {
								max1.remove(max1.size() -1);
								max1.add( (Integer)(contoursJ.get(i).get(j)) );
								//System.out.println("add max1 "+(max1.size() -1)+" "+(Integer)(contoursJ.get(i).get(j)));
							}
							////////result////begin////
/*							if ( (Integer)(contoursI.get(i).get(j)) < (Integer)(min1.get(min1.size() -1)) ) {
								min1.remove(min1.size() -1);
								min1.add((Integer)(contoursJ.get(i).get(j)));
								System.out.println("add min1 "+(min1.size() -1)+" "+(Integer)(contoursJ.get(i).get(j)));
							}*/
							//////result/////end//////
						}
						
					}
				} else {
					if ( ( (Integer)(contoursI.get(i).get(0)) < (Integer)(redJ.get(k)) ) &&
						( (Integer)(contoursI.get(i).get(0)) > (Integer)(redJ.get(k-1)) ) ) {
						
						min1.add((Integer)(contoursJ.get(i).get(0)));
						max1.add((Integer)(contoursJ.get(i).get(0)));
						
						for (int j = 0; j < contoursJ.get(i).size(); j++) {
							if ( (Integer)(contoursJ.get(i).get(j)) < (Integer)(min1.get(min1.size() -1)) ) {
								min1.remove(min1.size() -1);
								min1.add((Integer)(contoursJ.get(i).get(j)));
								//System.out.println("add min1 "+(min1.size() -1)+" "+(Integer)(contoursJ.get(i).get(j)));
							}
							if ( (Integer)(contoursJ.get(i).get(j)) > (Integer)(max1.get(max1.size() -1)) ) {
								max1.remove(max1.size() -1);
								max1.add( (Integer)(contoursJ.get(i).get(j)) );
								//System.out.println("add max1 "+(max1.size() -1)+" "+(Integer)(contoursJ.get(i).get(j)));
							}
						}						
					}
				}
				//System.out.println("add min1 "+i+" "+(Integer)(contoursJ.get(i).get(0)));
				
/*				for (int j = 0; j < contoursJ.get(i).size(); j++) {
					if ( (Integer)(redJ.get(k)) < 100 )
						if ((Integer)(contoursI.get(i).get(j)) < 100)
							System.out.println("red "+(Integer)(redJ.get(k))+" conI "+(Integer)(contoursI.get(i).get(j))+" conJ "+(Integer)(contoursJ.get(i).get(j)));

					if (k == 0) {
						if ( (Integer)(contoursI.get(i).get(j)) < (Integer)(redJ.get(k)) )  {
							if ( (Integer)(contoursJ.get(i).get(j)) < (Integer)(min1.get(min1.size() -1)) ) {
								min1.remove(min1.size() -1);
								min1.add((Integer)(contoursJ.get(i).get(j)));
								System.out.println("add min1 "+(min1.size() -1)+" "+(Integer)(contoursJ.get(i).get(j)));
							}
							if ( (Integer)(contoursJ.get(i).get(j)) > (Integer)(max1.get(max1.size() -1)) ) {
								max1.remove(max1.size() -1);
								max1.add( (Integer)(contoursJ.get(i).get(j)) );
								System.out.println("add max1 "+(max1.size() -1)+" "+(Integer)(contoursJ.get(i).get(j)));
							}
						} 
					} else {
						if ( ( (Integer)(contoursI.get(i).get(j)) < (Integer)(redJ.get(k)) ) &&
							( (Integer)(contoursI.get(i).get(j)) > (Integer)(redJ.get(k-1)) ) ) {
					
							if ( (Integer)(contoursJ.get(i).get(j)) < (Integer)(min1.get(min1.size() -1)) ) {
								min1.remove(min1.size() -1);
								min1.add((Integer)(contoursJ.get(i).get(j)));
								System.out.println("add min1 "+(min1.size() -1)+" "+(Integer)(contoursJ.get(i).get(j)));
							}
							if ( (Integer)(contoursJ.get(i).get(j)) > (Integer)(max1.get(max1.size() -1)) ) {
								max1.remove(max1.size() -1);
								max1.add( (Integer)(contoursJ.get(i).get(j)) );
								System.out.println("add max1 "+(max1.size() -1)+" "+(Integer)(contoursJ.get(i).get(j)));
							}
						}
					}
				}*/
			}
			min.add(min1);
			//for (int i = 0; i < min1.size(); i++) {
				//System.out.println("MIN1 "+i+" "+(Integer)(min1.get(i)));
			//}
			max.add(max1);
			//for (int i = 0; i < max1.size(); i++) {
				//System.out.println("MAX1 "+i+" "+(Integer)(max1.get(i)));
			//}
		}
		
		//for (int i = 0; i < max.size(); i++) {
			//System.out.println(" max.get(i).size() "+ max.get(i).size());
			//for (int j = 0; j < max.get(i).size(); j++) {
				//System.out.println("min, max "+i+" "+min.get(i).get(j)+", "+max.get(i).get(j));
			//}
		//}
		
		ArrayList delI = new ArrayList();
		ArrayList delJ = new ArrayList();
		
		for (int i = 0; i < min.size(); i++) {
			for (int j = 0; j < min.get(i).size(); j++) {
				for (int k = 0; k < min.get(i).size(); k++) {
					if (k != j)
					if ( ( (Integer)(min.get(i).get(j)) >=  (Integer)(min.get(i).get(k)) ) &&
						( (Integer)(max.get(i).get(j)) <=  (Integer)(max.get(i).get(k)) ) ) {
						delI.add(i);
						delJ.add(j);
					}
				}
			}
		}
		
		//System.out.println("PRED");
		//for (int i = 0; i < max.size(); i++) {
			//for (int j = 0; j < max.get(i).size(); j++) {
				//System.out.println("min, max "+i+" "+min.get(i).get(j)+", "+max.get(i).get(j));
			//}
		//}
		
//		TODO opravit!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	//	System.out.println("min.size() "+min.size());
	//	System.out.println("max.size() "+max.size());
/*		for (int i = 0; i < delI.size(); i++) {
			//min.get(i).set(index, element)
			for (int j = (Integer)(delJ.get(i)); j < min.get((Integer)(delI.get(i))).size() -1; j++) {
				min.get((Integer)(delI.get(i))).set(j, min.get((Integer)(delI.get(i))).get(j+1));
				max.get((Integer)(delI.get(i))).set(j, max.get((Integer)(delI.get(i))).get(j+1));
			}
			min.get((Integer)(delI.get(i))).remove(min.get((Integer)(delI.get(i))).size() - 1);
			max.get((Integer)(delI.get(i))).remove(max.get((Integer)(delI.get(i))).size() - 1);
		}*/
		
		for (int i = 0; i < delI.size(); i++) {
			min.get((Integer)(delI.get(i))).set((Integer)(delJ.get(i)), -1);
			max.get((Integer)(delI.get(i))).set((Integer)(delJ.get(i)), -1);
		}
	//	System.out.println("PO");
	//	for (int i = 0; i < max.size(); i++) {
	//		for (int j = 0; j < max.get(i).size(); j++) {
				//System.out.println("min, max "+i+" "+min.get(i).get(j)+", "+max.get(i).get(j));
	//		}
	//	}
		
		int[][] sortMin = new int[min.size()][];
		int[][] sortMax = new int[max.size()][];
		
		for (int i = 0; i < sortMax.length; i++) {
			sortMin[i] = new int[min.get(i).size()];
			sortMax[i] = new int[max.get(i).size()];
			for (int j = 0; j < min.get(i).size(); j++) {
					sortMin[i][j] = (Integer)(min.get(i).get(j));
					sortMax[i][j] = (Integer)(max.get(i).get(j));
			}
		}
		
		for (int i = 0; i < sortMax.length; i++) {
			Arrays.sort(sortMin[i]);
			//Arrays.sort(sortMax[i]);
		}
		
		for (int i = 0; i < sortMin.length; i++) {
			for (int j = 0; j < sortMin[i].length; j++) {
				for (int k = 0; k < min.get(i).size(); k++) {
					if (sortMin[i][j] == (Integer)(min.get(i).get(k)))
						sortMax[i][j] = (Integer)(max.get(i).get(k));
				}
			}
		}
		
		
	//	System.out.println();
	//	for (int i = 0; i < sortMin.length; i++) {
	//		for (int j = 0; j < sortMin[i].length; j++) {
				//System.out.println("sortmin, sortmax "+sortMin[i][j]+", "+sortMax[i][j]);
	//		}
	//	}
		
		int[][] dif = new int[sortMax.length][];
		for (int i = 0; i < sortMax.length; i++) {
			if ( sortMax[i].length >0 ) {
				dif[i] = new int[sortMax[i].length - 1];
				for (int j = 0; j < sortMax[i].length; j++) {
					if (j!= sortMax[i].length-1) {
						if ((sortMin[i][j+1] > 0) && (sortMax[i][j] > 0))
							dif[i][j] = sortMin[i][j+1] - sortMax[i][j];
						else dif[i][j] = 0;
						//System.out.println("dif "+dif[i][j]);
					}
				}
			} else 
				dif[i] = new int[0];
		}
		
		int[][] sortDif = new int[dif.length][];
		
		for (int i = 0; i < sortDif.length; i++) {
			sortDif[i] = new int[dif[i].length];
			for (int j = 0; j < dif[i].length; j++) {
				sortDif[i][j] = dif[i][j];
			//	System.out.println("sortDif "+sortDif[i][j]);
			}
		}
	//	System.out.println();
	//	for (int i = 0; i < sortDif.length; i++) 
	//	for (int j = 0; j < sortDif[i].length; j++) {
			//System.out.println("dif "+i+" "+j+" "+sortDif[i][j]);
	//	}
		
		for (int i = 0; i < sortDif.length; i++)
			Arrays.sort(sortDif[i]);
	
	//	for (int i = 0; i < dif.length; i++) {
			//System.out.println("dif "+dif[i]);
	//	}
	
	//	for (int i = 0; i < sortDif.length; i++) 
	//	for (int j = 0; j < sortDif[i].length; j++) {
			//System.out.println("sortDif "+i+" "+j+" "+sortDif[i][j]);
	//	}
		
/*		double[] average = new double[sortDif.length];
		for (int i = 0; i < sortDif.length; i++) {
			int maxDif = 0;
			int aver = 0;
			for (int j = 1; j < sortDif[i].length; j++) {
				if ((sortDif[i][j] - sortDif[i][j-1]) > maxDif) {
					maxDif = sortDif[i][j] - sortDif[i][j-1];
					aver = sortDif[i][j];
				}
			}
			average[i] = aver;
		}*/
		
		double[] average = new double[sortDif.length];
		int[] count = new int[average.length];
		
		for (int i = 0; i < sortDif.length; i++) {
			for (int j = 0; j < sortDif[i].length; j++) {
				if ( sortDif[i][j] > 0 ) {
					average[i] = average[i] + sortDif[i][j];
					count[i]++;
				}
			}
		}
		for (int i = 0; i < average.length; i++) {
			average[i] = average[i] / (count[i] );
			//System.out.println("average "+average[i]);
		}
		
//		menim average kvoli dilatation 
/*		double averageNew = 0;
		for (int i = 0; i < average.length; i++) {
			averageNew = average[i] + averageNew;
			System.out.println("average "+average[i]);
		}		
		averageNew = averageNew / average.length;
		averageNew = averageNew / 2;
*/		
//		System.out.println("averageNew "+averageNew);
		ImagePlus impSepChar = NewImage.createRGBImage ("Word Segmentation", ip.getWidth(), ip.getHeight(), 1, NewImage.FILL_WHITE);
		ImageProcessor nipSepChar = impSepChar.getProcessor();
		
		for (int i = 0; i < ip.getWidth(); i++) {
			for (int j = 0; j < ip.getHeight(); j++) {			
				nipSepChar.putPixel(i, j, ip.getPixel(i, j));
			}
		}
		
		//System.out.println("Chyba");
		color = ((Color.red.getRed() & 0xff) << 16) + ((0 & 0xff) << 8) + (0 & 0xff);
		int color2 = ((0 & 0xff) << 16) + ((0 & 0xff) << 8) + (Color.blue.getBlue() & 0xff);
		
		nipSepChar.setColor(color);
		double[] resultWords = new double[redJ.size()]; //TODO toto spadne obcas
		double[] countResultWords = new double[redJ.size()]; //TODO toto spadne obcas
		double[] countResultSegmetsWords = new double[redJ.size()]; //TODO toto spadne obcas
		double[] countResultRatio = new double[redJ.size()]; //TODO toto spadne obcas
	//	int i = 0;
		double kresli = 0;
		for (int i = 0; i < dif.length; i++) {
			if (!kresliModre) kresli = average[i];
			else kresli = 0;
			for (int j = 0; j < dif[i].length; j++) {
					if (dif[i][j] > 0) 
						nipSepChar.setColor(color2);
					if (dif[i][j] > average[i])
						nipSepChar.setColor(color);
				
					if (dif[i][j] > kresli) { //zmena aby vykreslovalo len oddelenie slov
						int center = ((sortMin[i][j+1] - sortMax[i][j]) / 2) + sortMax[i][j];
						if (dif[i][j] > average[i]) {
							resultWords[i] = resultWords[i] + (sortMin[i][j+1] - sortMax[i][j]);
							countResultWords[i] = countResultWords[i] + 1;
						}
						if (dif[i][j] > 0) {
							countResultSegmetsWords[i] = countResultSegmetsWords[i] + 1;
						}
						if (i == 0)
							nipSepChar.drawLine(center, 0, center, (Integer)(redJ.get(i)));
						else 
							nipSepChar.drawLine(center, (Integer)(redJ.get(i - 1)), center, (Integer)(redJ.get(i)));
					}
			}
		}
		
		for (int i = 0; i < countResultWords.length; i++) {
			resultWords[i] = resultWords[i] / countResultWords[i];
		//	System.out.println("resultWords[i] "+resultWords[i]);
		}
		
		for (int i = 0; i < countResultRatio.length; i++) {
			countResultRatio[i] = (countResultSegmetsWords[i] + 1) / (countResultWords[i] + 1);
		//	System.out.println("countResultRatio[i] "+countResultRatio[i]);
		}
		
		//pixle TODO zmenit na percentualnost
		Result.setDiffWords(resultWords, numberResult);
		
		//palickovost
		Result.setRatioWordsSegments(countResultRatio, numberResult);
		
	//	System.out.println("Chyba");
		
		if (draw3) {
			//nip2
			mainWindow.intFrameArrayList.add(new internalFrame("Word Segmentation", impSepChar, 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;
		}
		
		//System.out.println("Chyba");
		
		System.runFinalization();
		System.gc();
		
		return nipSepChar;
	}
	
	
	////SAVE GRAPHEMES////////////////////////////////////////////////////////
	public void saveGraphemes(int scale, ImageProcessor ip){
		
		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) ) {
	/*						if (i > 500)
								System.out.println("ZASEKAVAM SA??moore");*/
							int j = (Integer)(redItop.get(q)) + 1;
							while ( (j < (Integer)(redIbottom.get(q))) && (deleteLeft) ) {
					/*			if (j > 500)
									System.out.println("ZASEKAVAM SA??moore");*/
								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) ) {
							//System.out.println("ZASEKAVAM SA??");
							int j = (Integer)(redItop.get(q)) + 1;
							while ( (j < (Integer)(redIbottom.get(q))) && (deleteRight) ) {
/*								if (j > 500)
								System.out.println("ZASEKAVAM SA??moore");*/
								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) ) {
/*							if (j > 500)
							System.out.println("ZASEKAVAM SA??moore");*/
							i = (Integer)(redJleft.get(q)) + 1;
							while ( (i < (Integer)(redJright.get(q))) && (deleteTop) ) {
				/*				if (i > 500)
								System.out.println("ZASEKAVAM SA??moore");*/
								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) ) {
							//System.out.println("ZASEKAVAM SA??");
							i = (Integer)(redJleft.get(q)) + 1;
							while ( (i < (Integer)(redJright.get(q))) && (deleteBottom) ) {
/*								if (i > 500)
								System.out.println("ZASEKAVAM SA??moore");*/
								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("Segmented and normalized graphemes", 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;	
		}
		
		
		System.runFinalization();
		System.gc();
	}	
	
	public ImagePlus getImg(){
		return impSepAll;
	}
	
	public ImageProcessor getIp(){
		return ipSepAll;
	}	
	
	protected void finalize() throws Throwable {
	    try {
	        //close();        // close open files
	    } finally {
	        super.finalize();
	        System.out.println("moore has been finalized.");
	    }
	}	

}
