package representation;
	/*
	 * MooreNeighbor.java
	 *
	 * Created on 26 noiembrie 2005, 23:13
	 *
	 * To change this template, choose Tools | Options and locate the template under
	 * the Source Creation and Management node. Right-click the template and choose
	 * Open. You can then make changes to the template in the Source Editor.
	 */

	/**
	 *
	 * @author Strainu
	 */
	import ij.ImagePlus;
	import ij.gui.NewImage;
	import ij.process.ImageProcessor;
	import javax.swing.event.*;
	import javax.swing.*;

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

	import java.awt.event.*;
	import java.awt.*;
import java.util.*;


	public class Moore2 {
		
		ImagePlus imp;
		ImagePlus imp2;
		ImagePlus imp3, impSepChar, impSepAll, impOtsu;
		ImageProcessor ip, nipOtsu;
		ImageProcessor nip, nipSepChar, ipSepAll;
		ImageProcessor nip2;
		int numberResult;
		boolean draw;
		
    	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

		
		public Moore2(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) {
						System.out.println("not empty "+i+" "+j);
						return false;
					}
				}
			}	    	
			System.out.println("empty ");
			return true;
	    }
	    
	    /**algoritmul MooreNeighbor*/
	    public void algoritm(){
			imp2 = NewImage.createRGBImage ("Moore's algorithm", ip.getWidth(), ip.getHeight(), 1, NewImage.FILL_WHITE);
			nip = imp2.getProcessor();	//m2
			
			ImagePlus imp3 = NewImage.createRGBImage ("Moore's algorithm", ip.getWidth(), ip.getHeight(), 1, NewImage.FILL_WHITE);
			ImageProcessor nip2 = imp3.getProcessor();//m1
			
				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;
				        
			while (emptyImage(nip2) == false) {
			        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);
//			                    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{
			        	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;
			        }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);
					}
					
			    }
			//nip
			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;
*/			
	}
	    
}