package representation;

import GUI.FileChooser;
import GUI.internalFrame;
import GUI.mainWindow;
import ij.*;
import ij.gui.NewImage;
import ij.process.ImageProcessor;
import java.util.*;
import java.io.*;
import java.awt.Color;

public class ChainCode {
	
	ImagePlus imp;
	ImagePlus imp2;
	ImageProcessor ip;
	ImageProcessor nip;
	int numberResult;
	
	class chainCodeRepr{
		ArrayList x;
		ArrayList y;
		Random random = new Random();
		Color randomColor = Color.getHSBColor( random.nextFloat(), 1.0F, 1.0F );
	}
	
	public ChainCode(ImagePlus imp, ImageProcessor ip, int numberResult) {
		this.imp = imp;
		this.ip = ip;
		this.numberResult = numberResult;
	}
	
	private chainCodeRepr findWholeContour(int i, int j, chainCodeRepr ccr) {
		
		if ((i == 0) && (j == 0)) {
			nip.putPixelValue(i, j, 255);
			if (nip.getPixelValue(i, j+1) == 0) {
				j = j+1;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if (nip.getPixelValue(i+1, j) == 0) {
				i = i+1;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if (nip.getPixelValue(i+1, j+1) == 0) {
				i = i+1;
				j = j+1;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
		} else if ((i>0)&& (i<nip.getWidth()-1) &&(j == 0)) {
			nip.putPixelValue(i, j, 255);
			if (nip.getPixelValue(i-1, j) == 0) {
				i = i -1;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if (nip.getPixelValue(i-1, j+1) == 0) {
				i = i-1; j = j+1;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			} 
			if (nip.getPixelValue(i, j+1) == 0) {
				j = j+1;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if (nip.getPixelValue(i+1, j) == 0) {
				i = i+1;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if (nip.getPixelValue(i+1, j+1) == 0) {
				i = i +1;
				j = j+1;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
		} else if ((i == nip.getWidth()-1) && (j==0)) {
			nip.putPixelValue(i, j, 255);
			if (nip.getPixelValue(i, j-1) == 0) {
				j = j-1;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if (nip.getPixelValue(i+1, j-1) == 0) {
				i = i+1; j = j-1;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			} 
			if (nip.getPixelValue(i+1, j) == 0) {
				i++;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
		} else if ((i == 0) && (j>0) && (j<nip.getHeight()-1)) {
			nip.putPixelValue(i, j, 255);
			if (nip.getPixelValue(i, j-1) == 0) {
				j--;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if (nip.getPixelValue(i, j+1) == 0) {
				j++;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if (nip.getPixelValue(i+1, j-1) == 0) {
				i++; j--;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			} 
			if (nip.getPixelValue(i+1, j) == 0) {
				i++;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if (nip.getPixelValue(i+1, j+1) == 0) {
				i++; j++;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
		} else if ((i>0) && (i<nip.getWidth()-1)&& (j>0) && (j<nip.getHeight()-1)) {
			nip.putPixelValue(i, j, 255);
			if (nip.getPixelValue(i-1, j-1) == 0) {
				i--; j--; 
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			} 
			if	(nip.getPixelValue(i-1, j) == 0) {
				i--;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if	(nip.getPixelValue(i-1, j+1) == 0) {
				i--; j++;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			} 
			if	(nip.getPixelValue(i, j-1) == 0) {
				j--;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if	(nip.getPixelValue(i, j+1) == 0) {
				j++;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if	(nip.getPixelValue(i+1, j-1) == 0) {
				i++; j--;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			} 
			if	(nip.getPixelValue(i+1, j) == 0) {
				i++;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if	(nip.getPixelValue(i+1, j+1) == 0) {
				i++; j++;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
		} else if ((i==nip.getWidth()-1)&& (j>0) && (j<nip.getHeight()-1)) {
			nip.putPixelValue(i, j, 255);
			if (nip.getPixelValue(i-1, j-1) == 0) {
				i--; j--;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			} 
			if	(nip.getPixelValue(i-1, j) == 0) {
				i--;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if	(nip.getPixelValue(i-1, j+1) == 0) {
				i--; j++;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			} 
			if	(nip.getPixelValue(i, j-1) == 0) {
				j--;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if	(nip.getPixelValue(i, j+1) == 0) {
				j++;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
		} else if ((i==0) && (j==nip.getHeight()-1)) {
			nip.putPixelValue(i, j, 255);
			if (nip.getPixelValue(i, j-1) == 0) {
				j--;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if (nip.getPixelValue(i+1, j-1) == 0) {
				i++; j--; 
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			} 
			if	(nip.getPixelValue(i+1, j) == 0) {
				i++;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
		} else if ((i>0) && (i<nip.getWidth()-1)&& (j==nip.getHeight()-1)) {
			nip.putPixelValue(i, j, 255);
			if (nip.getPixelValue(i-1, j-1) == 0) {
				i--; j--; 
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			} 
			if (nip.getPixelValue(i-1, j) == 0) {
				i--;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if	(nip.getPixelValue(i, j-1) == 0) {
				j--;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if	(nip.getPixelValue(i+1, j-1) == 0) {
				i++; j--;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			} 
			if	(nip.getPixelValue(i+1, j) == 0) {
				i++;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
		} else if ((i==nip.getWidth()-1)&& (j==nip.getHeight()-1)) {
			nip.putPixelValue(i, j, 255);
			if (nip.getPixelValue(i-1, j-1) == 0) {
				i--; j--; 
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			} 
			if (nip.getPixelValue(i-1, j) == 0) {
				i--;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
			if	(nip.getPixelValue(i, j-1) == 0) {
				j--;
				ccr.x.add(ccr.x.size(), i);
				ccr.y.add(ccr.y.size(), j);
				findWholeContour(i, j, ccr);
			}
		}
		return ccr;
	}
	
	public void run(){
		
		imp2 = NewImage.createRGBImage ("ChainCode", ip.getWidth(), ip.getHeight(), 1, NewImage.FILL_WHITE);
		nip = imp2.getProcessor();	
		
		for (int i = 0; i < ip.getHeight(); i++) {
			for (int j = 0; j < ip.getWidth(); j++) {
				if (j != ip.getWidth() -1) {
					if ((ip.getPixelValue(j, i) == 255) && (ip.getPixelValue(j+1, i) == 0) ) {
						nip.putPixelValue(j+1, i, 0);
					}
					if ((ip.getPixelValue(j, i) == 0) && (ip.getPixelValue(j+1, i) == 255) )
						nip.putPixelValue(j, i, 0);
				}
			}
		}
		
		for (int i = 0; i < ip.getWidth(); i++) {
			for (int j = 0; j < ip.getHeight(); j++) {
				if (j != ip.getHeight() -1) {
					if ((ip.getPixelValue(i, j) == 255) && (ip.getPixelValue(i, j+1) == 0) )
						nip.putPixelValue(i, j+1, 0);
					if  ((ip.getPixelValue(i, j) == 0) && (ip.getPixelValue(i, j+1) == 255) )
						nip.putPixelValue(i, j, 0);
				}
			}
		}
		
		//nip
		mainWindow.intFrameArrayList.add(new internalFrame(imp2.getTitle()+ " - Chain Code", 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;	
		
		ImagePlus imp3 = NewImage.createRGBImage ("ChainCode", nip.getWidth(), nip.getHeight(), 1, NewImage.FILL_WHITE);
		
		ImageProcessor nip2 = imp3.getProcessor();	
		
		int i=0, j=0;
		i=0; j=0;
		while ((nip.getPixelValue(i, j) != 0) && (j != nip.getHeight() -1)) {
			if (i < nip.getWidth()-1) i++;
			else {
				i = 0;
				j++;
			}
		}
		int initI = i;
		int initJ = j;
		
		ArrayList maxX = new ArrayList();
		
		//int x=0,y=0;
		
		while ( nip.getPixelValue(i, j) == 0 ) {
		
			chainCodeRepr ccr = new chainCodeRepr();
			int k = 0;
			ccr.x = new ArrayList();
			ccr.y = new ArrayList();
			
			ccr.x.add(k, i);
			ccr.y.add(k, j);
			findWholeContour(i, j, ccr);
				
			//System.out.println(nip.getPixelValue(i, j));					
			int max = 0;
			for (j = 0; j < ccr.y.size(); j++) {
				int color = ((ccr.randomColor.getRed() & 0xff) << 16) + ((ccr.randomColor.getGreen() & 0xff) << 8) + (ccr.randomColor.getBlue() & 0xff);
				nip2.putPixel((Integer)(ccr.x.get(j)), (Integer)(ccr.y.get(j)), color);
				nip.putPixelValue((Integer)(ccr.x.get(j)), (Integer)(ccr.y.get(j)), 255);
				//System.out.println(nip.getPixelValue((Integer)(ccr.x.get(j)), (Integer)(ccr.y.get(j))));
				if ((Integer)(ccr.x.get(j)) > max) 
					max = (Integer)(ccr.x.get(j));
/*				if (j== ccr.y.size()-1) {
					mainWindow.intFrame[FileChooser.number] = new internalFrame(imp3.getTitle()+ " - Chain Code", imp3, FileChooser.number);
					try {
						mainWindow.intFrame[FileChooser.number].setSelected(true);
					} catch(Exception e){
						System.out.println("Chyba");
					}	
					++FileChooser.number;	
				}*/
			}
			
			maxX.add(max);
				
			i=initI; j=initJ;
			while ((nip.getPixelValue(i, j) != 0) && (j != nip.getHeight() -1)) {
				if (i < nip.getWidth()-1) i++;
				else {
					i = 0;
					j++;
				}
			}
			initI = i;
			initJ = j;
			
		}//end while
		
		//System.out.println("x,y "+nip.getPixelValue(x, y));
		
		//z arraylistov
		
		int[] m = new int[maxX.size()];
		for (int k = 0; k < m.length; k++) {
			m[k] = (Integer)(maxX.get(k));
		}

		//Arrays.sort(m);
		for (int k = 0; k < m.length; k++) {
			System.out.println("m "+m[k]);
		}
		
		mainWindow.intFrameArrayList.add(new internalFrame(imp3.getTitle()+ " - Chain Code", imp3, 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.intFrameArrayList.add(new internalFrame(imp2.getTitle()+ " - Chain Code", 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;	
	}
	
}
