package representation;

import java.awt.Color;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;

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

import ij.ImagePlus;
import ij.gui.NewImage;
import ij.process.ImageProcessor;
import java.util.List;

public class HorizontalRunLength {
	
	ImagePlus imp, imp2;
	ImageProcessor ip, nip;	
	int numberResult;

	class horRunLength{
		int r; //the row of horizontal run
		int c1, c2; //first and last columns of the run
		int len; //lenght of the run
		int traced; //tracing indicator
		ArrayList above, below, right;
	}	
	
	class slopes{
		int x1,x2,y1,y2;
		double angle;
		double multi;
		double prepona;
	}
	
	private boolean areRunsNeighbours(horRunLength above, horRunLength below){
		if (above.c2 < below.c1) return false;
		if (above.c1 > below.c2) return false;
		return true;
	}
	
	class contours{
		ArrayList con;
	}
	
	
	public HorizontalRunLength(ImagePlus imp, ImageProcessor ip, int numberResult) {
		this.imp = imp;
		this.ip = ip;
		this.numberResult = numberResult;
		
		int color = ((Color.red.getRed() & 0xff) << 16) + ((0 & 0xff) << 8) + (0 & 0xff); //red color
		
		ArrayList redJ = new ArrayList();
		
			for (int j = 0; j < ip.getHeight(); j++) {			
				if (ip.getPixel(0, j) == color) {
					redJ.add(j);
					System.out.println("red "+j);
				}
			}
			
		ImagePlus imp4 = NewImage.createByteImage ("Horizontal Run Length", ip.getWidth(), ip.getHeight(), 1, NewImage.FILL_WHITE);
		ImageProcessor nip3 = imp4.getProcessor();	
			
		ImagePlus imp5 = NewImage.createRGBImage ("Horizontal Run Length", ip.getWidth(), ip.getHeight(), 1, NewImage.FILL_WHITE);
		ImageProcessor nip4 = imp5.getProcessor();	
			
		//for (int kk = 0; kk < redJ.size(); kk++) {
			for (int kk = 0; kk < 1; kk++) {		
		
					ArrayList list = new ArrayList();
					
					int i = 0;
					int j = 0;
					if (kk == 0)
						j = 0;
					else 
						j = (Integer)(redJ.get(kk-1));
					while (j<(Integer)(redJ.get(kk))) {
						i = 0;
						while (i<ip.getWidth()){
							if (ip.getPixelValue(i, j) == 0) {
								if  ((i == 0) || ( (i != 0) && (ip.getPixelValue(i-1, j) == 255) )) {
									horRunLength hrl = new horRunLength();
									hrl.r = j;
									hrl.c1 = i;
									while (ip.getPixelValue(i, j) == 0)
										i++;
									hrl.c2 = i-1;
									hrl.len = hrl.c2 - hrl.c1 + 1;
									hrl.above = new ArrayList();
									hrl.below = new ArrayList();
									hrl.right = new ArrayList();
									for (int k = 0; k < list.size(); k++) {
										horRunLength hrl2 = ((horRunLength)(list.get(k)));
										if ( ((hrl2.r + 1) == hrl.r) && (areRunsNeighbours(hrl2, hrl)) ){
											hrl.above.add(k);
											hrl2.below.add(list.size());
										}
										if ((k == list.size() -1) && (hrl2.r == hrl.r))
											hrl2.right.add(list.size());
									}
									list.add(hrl);
								}
									
							}
							i++;
						}
						j++;
					}
					
					
					ImagePlus imp2 = NewImage.createRGBImage ("Horizontal Run Length", ip.getWidth(), ip.getHeight(), 1, NewImage.FILL_WHITE);
					ImageProcessor nip = imp2.getProcessor();
					
					Random random = new Random();
					Color randomColor = Color.getHSBColor( random.nextFloat(), 1.0F, 1.0F );
			
/*					for (i = 0; i < list.size(); i++) {
						horRunLength hrl = ((horRunLength)(list.get(i)));
						randomColor = Color.getHSBColor( random.nextFloat(), 1.0F, 1.0F );
			
						color = ((randomColor.getRed() & 0xff) << 16) + ((randomColor.getGreen() & 0xff) << 8) + (randomColor.getBlue() & 0xff);
			
						for (int k = 0; k < hrl.len; k++) {
							nip.putPixel(hrl.c1 + k, hrl.r, color);
						}
					}*/
					
					ArrayList list2 = new ArrayList();
					for (int k = 0; k < list.size(); k++) {
						horRunLength hrl = ((horRunLength)(list.get(k)));
						if (list2.isEmpty())
							list2.add(hrl);
						else {
							int index = 0;
							while (( index < list2.size()) &&  ( hrl.c1 >= ((horRunLength)(list2.get(index))).c1 ) ){
								index++;
							}
							//System.out.println("hrl.c1 "+hrl.c1);
						//	System.out.println("((horRunLength)(list2.get(index))).c1 "+((horRunLength)(list2.get(index))).c1);
							if ( index < list2.size()) {
									ArrayList list3 = new ArrayList();
									for (int l = 0; l < list2.size(); l++) {
										if (l != index)
											list3.add(list2.get(l));
										else {
											list3.add(hrl);
											list3.add(list2.get(index));
										}
									}
									list2 = list3;
								} else 
									list2.add(hrl);
						}
					}
					
					list = list2;
					
					for (i = 0; i < list.size() / 2; i++) {
						horRunLength hrl = ((horRunLength)(list.get(i)));
						randomColor = Color.getHSBColor( random.nextFloat(), 1.0F, 1.0F );
			
						color = ((randomColor.getRed() & 0xff) << 16) + ((randomColor.getGreen() & 0xff) << 8) + (randomColor.getBlue() & 0xff);
			
						//for (int k = 0; k < hrl.len; k++) {
							nip.putPixel(hrl.c1, hrl.r, color);
							System.out.println("hrl.c1 "+hrl.c1);
							System.out.println("hrl.r "+hrl.r);
						//}
					}
					
					mainWindow.intFrameArrayList.add(new internalFrame("Horizontal Run Length", 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;
					
					//DETECTION SLANT ANGLE
					//left and right contours
					ImagePlus imp3 = NewImage.createRGBImage ("Left and right contours", ip.getWidth(), ip.getHeight(), 1, NewImage.FILL_WHITE);
					ImageProcessor nip2 = imp3.getProcessor();
					
				//	contours[] left, right;
				//	left = new contours[3];
				//	right = new contours[3];
					
/*					ArrayList<ArrayList> left = new ArrayList<ArrayList>();
					//List<String[]> list2 = new ArrayList<String[]>();
					
					
					for (i = 0; i < list.size(); i++) {
						horRunLength hrl = ((horRunLength)(list.get(i)));
			
						if (left.isEmpty()) {
							ArrayList l = new ArrayList();
							l.add(hrl);
							left.add(l);
						} else {
							int k = 0;
							while ((k<left.size()) && (Math.abs(((horRunLength)(left.get(k).get(left.get(k).size() - 1))).c1 - hrl.c1) > 2)) {
								k++;
							}
							if (k == left.size())
								k--;
							horRunLength getHrl = ((horRunLength)(left.get(k).get(left.get(k).size() - 1)));
							if (Math.abs(getHrl.c1 - hrl.c1) <= 2) {
								left.get(k).add(hrl);
							} else {
								ArrayList l = new ArrayList();
								l.add(hrl);
								left.add(l);				
							}
						}
			
					}
					
					imp2 = NewImage.createRGBImage ("Horizontal Run Length", ip.getWidth(), ip.getHeight(), 1, NewImage.FILL_WHITE);
					nip = imp2.getProcessor();
					
					random = new Random();
					randomColor = Color.getHSBColor( random.nextFloat(), 1.0F, 1.0F );
					
					for (int k = 0; k < left.size(); k++) {
						randomColor = Color.getHSBColor( random.nextFloat(), 1.0F, 1.0F );
						
						color = ((randomColor.getRed() & 0xff) << 16) + ((randomColor.getGreen() & 0xff) << 8) + (randomColor.getBlue() & 0xff);

						for (int index = 0; index < left.get(k).size()/2; index++) {
								nip.putPixel(((horRunLength)(left.get(k).get(index))).c1, ((horRunLength)(left.get(k).get(index))).r, color);
						}
					}
		*/	
					
/*					mainWindow.intFrame[FileChooser.number] = new internalFrame("Horizontal Run Length", imp2, FileChooser.number, numberResult);
					try {
						mainWindow.intFrame[FileChooser.number].setSelected(true);
					} catch(Exception e){
						System.out.println("Chyba");
					}	
					++FileChooser.number;*/
					/////////////////////////////////////////////////////////
					
					int[] slopeLeft;
					slopeLeft = new int[list.size()];
					
					for (int index = 0; index < list.size(); index++) {
						//slopeLeft[k] = new int[list.get(k).size()];
						horRunLength hrl = ((horRunLength)(list.get(index)));
							
							if ((index-1) >= 0) {
								horRunLength hrl2 = ((horRunLength)(list.get(index-1)));
								if (Math.abs(hrl.c1 - hrl2.c1) <= 1)
									slopeLeft[index] = slopeLeft[index] + Math.abs(hrl.c1 - hrl2.c1);
								else slopeLeft[index] = slopeLeft[index] + 2;
							} else slopeLeft[index] = slopeLeft[index] + 2;
							
							if ((index-2) >= 0) {
								horRunLength hrl2 = ((horRunLength)(list.get(index-2)));
								if (Math.abs(((horRunLength)(list.get(index-1))).c1 - ((horRunLength)(list.get(index-2))).c1) <= 1)
									slopeLeft[index] = slopeLeft[index] + Math.abs(((horRunLength)(list.get(index-1))).c1 - ((horRunLength)(list.get(index-2))).c1);
								else slopeLeft[index] = slopeLeft[index] + 2;
							} else slopeLeft[index] = slopeLeft[index] + 2;
							
							if ((index+1) < list.size()) {
								horRunLength hrl2 = ((horRunLength)(list.get(index+1)));
								if (Math.abs(((horRunLength)(list.get(index))).c1 - ((horRunLength)(list.get(index+1))).c1) <= 1)
									slopeLeft[index] = slopeLeft[index] + Math.abs(((horRunLength)(list.get(index))).c1 - ((horRunLength)(list.get(index+1))).c1);
								else slopeLeft[index] = slopeLeft[index] + 2;
							} else slopeLeft[index] = slopeLeft[index] + 2;
							
							if ((index+2) < list.size()) {
								horRunLength hrl2 = ((horRunLength)(list.get(index+2)));
								if ( Math.abs(((horRunLength)(list.get(index+1))).c1 - ((horRunLength)(list.get(index+2))).c1) <= 1)
									slopeLeft[index] = slopeLeft[index] + Math.abs(((horRunLength)(list.get(index+1))).c1 - ((horRunLength)(list.get(index+2))).c1);
								else slopeLeft[index] = slopeLeft[index] + 2;
							} else slopeLeft[index] = slopeLeft[index] + 2;
							
							//System.out.println("slope[k][index] "+slope[k][index]);

					}
					
					ArrayList<slopes> slLeft = new ArrayList<slopes>();
					int k = 0;
					while (k < slopeLeft.length) {
						//j= 0;
						//while (j<left.get(k).size()) {
						horRunLength hrl = ((horRunLength)(list.get(k)));
							slopes s = new slopes();
							s.x1 = hrl.c1;
							s.y1 = hrl.r;
							System.out.println("s.x1 "+s.x1);
							System.out.println("s.y1 "+s.y1);
							k++;
							while ((k<list.size()) && (slopeLeft[k]<=5)) {
								k++;
								//if (j<left.get(k).size()) System.out.println("slopeLeft[k][j] !!!!! "+slopeLeft[k][j]);
							}
							
							if (k == list.size()){
								s.x2 = hrl.c1;
								s.y2 = hrl.r;
							} else {
								horRunLength hrl2 = ((horRunLength)(list.get(k)));
								s.x2 = hrl2.c1;
								s.y2 = hrl2.r;
							}
							System.out.println("s.x2 "+s.x2);
							System.out.println("s.y2 "+s.y2);
							double odvesnaPrilahla = Math.abs(s.y1 - s.y2);
							double odvesnaProtilahla = Math.abs(s.x1 - s.x2);
							//System.out.println("odvesnaPrilahla "+odvesnaPrilahla);
							//System.out.println("odvesnaProtilahla "+odvesnaProtilahla);
							double prepona = Math.sqrt(Math.pow(odvesnaPrilahla, 2) + Math.pow(odvesnaProtilahla, 2));
							s.prepona = prepona;
							double cosAngle = odvesnaPrilahla / prepona;
							//System.out.println("cosAngle "+cosAngle);
							if (odvesnaPrilahla == 0)
								s.angle = 0;
							else 
								s.angle = (Math.acos(cosAngle));
							s.multi = s.angle;// * prepona;
							System.out.println("s.angle "+s.angle);
							System.out.println("s.multi "+s.multi);
							System.out.println("s.prepona "+s.prepona);
							slLeft.add(s);
							k++;
						//}
					}					
					
					
/*					ArrayList<slopes> slLeft = new ArrayList<slopes>();
					for (int k = 0; k < slopeLeft.length; k++) {
						j= 0;
						while (j<left.get(k).size()) {
							slopes s = new slopes();
							s.x1 = ((horRunLength)(left.get(k).get(j))).c1;
							s.y1 = ((horRunLength)(left.get(k).get(j))).r;
							while ((j<left.get(k).size()) && (slopeLeft[k][j]<=5)) {
								j++;
								//if (j<left.get(k).size()) System.out.println("slopeLeft[k][j] !!!!! "+slopeLeft[k][j]);
							}
							if (j == left.get(k).size()){
								s.x2 = ((horRunLength)(left.get(k).get(0))).c1;
								s.y2 = ((horRunLength)(left.get(k).get(0))).r;
							} else {
								s.x2 = ((horRunLength)(left.get(k).get(j))).c1;
								s.y2 = ((horRunLength)(left.get(k).get(j))).r;
							}
							double odvesnaPrilahla = Math.abs(s.y1 - s.y2);
							double odvesnaProtilahla = Math.abs(s.x1 - s.x2);
							double prepona = Math.sqrt(Math.pow(odvesnaPrilahla, 2) + Math.pow(odvesnaProtilahla, 2));
							s.prepona = prepona;
							double cosAngle = odvesnaPrilahla / prepona;
							if (odvesnaPrilahla == 0)
								s.angle = 0;
							else 
								s.angle = Math.acos(cosAngle);
							s.multi = s.angle * prepona;
							System.out.println("s.multi "+s.multi);
							System.out.println("s.prepona "+s.prepona);
							slLeft.add(s);
							j++;
						}
					}*/
					
					
					///////////////////////
					
					ArrayList<ArrayList> right = new ArrayList<ArrayList>();
					
					for (i = 0; i < list.size(); i++) {
						horRunLength hrl = ((horRunLength)(list.get(i)));
			
						if (right.isEmpty()) {
							ArrayList l = new ArrayList();
							l.add(hrl);
							right.add(l);
						} else {
						
							k = 0;
							while ((k<right.size()) && (Math.abs(((horRunLength)(right.get(k).get(right.get(k).size() - 1))).c2 - hrl.c2) > 2)) {
								k++;
							}
							if (k == right.size())
								k--;
							
							horRunLength getHrl = ((horRunLength)(right.get(k).get(right.get(k).size() - 1)));
							if (Math.abs(getHrl.c2 - hrl.c2) <= 2) {
								right.get(k).add(hrl);
							} else {
								ArrayList l = new ArrayList();
								l.add(hrl);
								right.add(l);				
							}
						}
			
					}
					
					int[][] slopeRight;
					slopeRight = new int[right.size()][];
					
					for (k = 0; k < right.size(); k++) {
						slopeRight[k] = new int[right.get(k).size()];
						for (int index = 0; index < right.get(k).size(); index++) {
							
							if ((index-1) >= 0) {
								slopeRight[k][index] = slopeRight[k][index] + Math.abs(((horRunLength)(right.get(k).get(index))).c1 - ((horRunLength)(right.get(k).get(index-1))).c1);
							} else slopeRight[k][index] = slopeRight[k][index] + 2;
							
							if ((index-2) >= 0) {
								slopeRight[k][index] = slopeRight[k][index] + Math.abs(((horRunLength)(right.get(k).get(index-1))).c1 - ((horRunLength)(right.get(k).get(index-2))).c1);
							} else slopeRight[k][index] = slopeRight[k][index] + 2;
							
							if ((index+1) < right.get(k).size()) {
								slopeRight[k][index] = slopeRight[k][index] + Math.abs(((horRunLength)(right.get(k).get(index))).c1 - ((horRunLength)(right.get(k).get(index+1))).c1);
							} else slopeRight[k][index] = slopeRight[k][index] + 2;
							
							if ((index+2) < right.get(k).size()) {
								slopeRight[k][index] = slopeRight[k][index] + Math.abs(((horRunLength)(right.get(k).get(index+1))).c1 - ((horRunLength)(right.get(k).get(index+2))).c1);
							} else slopeRight[k][index] = slopeRight[k][index] + 2;
							
							//System.out.println("slope[k][index] "+slope[k][index]);
							
						}
					}
			
					
					ArrayList<slopes> slRight = new ArrayList<slopes>();
					for (k = 0; k < slopeRight.length; k++) {
						j= 0;
						while (j<right.get(k).size()) {
							slopes s = new slopes();
							s.x1 = ((horRunLength)(right.get(k).get(j))).c1;
							s.y1 = ((horRunLength)(right.get(k).get(j))).r;
							while ((j<right.get(k).size()) && (slopeRight[k][j]<=5)) {
								j++;
							}
							if (j == right.get(k).size()){
								s.x2 = ((horRunLength)(right.get(k).get(0))).c1;
								s.y2 = ((horRunLength)(right.get(k).get(0))).r;
							} else {
								s.x2 = ((horRunLength)(right.get(k).get(j))).c1;
								s.y2 = ((horRunLength)(right.get(k).get(j))).r;
							}
							double odvesnaPrilahla = Math.abs(s.y1 - s.y2);
							double odvesnaProtilahla = Math.abs(s.x1 - s.x2);
							double prepona = Math.sqrt(Math.pow(odvesnaPrilahla, 2) + Math.pow(odvesnaProtilahla, 2));
							s.prepona = prepona;
							double cosAngle = odvesnaPrilahla / prepona;
							if (odvesnaPrilahla == 0)
								s.angle = 0;
							else 
								s.angle = Math.acos(cosAngle);
							s.multi = s.angle;// * prepona;
							slRight.add(s);
							j++;
						}
					}
			////////////////////////////	
					//rozdelime na 5% useky, tj 20 casti
					
/*					double[] averageSlope = new double[20];
					double[] countPreponas = new double[20];
					for (int q = 0; q < countPreponas.length; q++) {
						for (int k = 0; k < slLeft.size(); k++) {
							if (q != (countPreponas.length -1))
								if ( ( (ip.getWidth() / 20 * q) <= ((slopes)slLeft.get(k)).x1) && ( (((slopes)slLeft.get(k)).x1) < ( (ip.getWidth() / 20 * (q+1))  ) ) ){
									if (((slopes)slLeft.get(k)).angle != 0) {
										averageSlope[q] = averageSlope[q] + ((slopes)slLeft.get(k)).multi;
										countPreponas[q] = countPreponas[q] + ((slopes)slLeft.get(k)).prepona;
									}
								}
						}
					}
					
					for (int q = 0; q < countPreponas.length; q++) {
						for (int k = 0; k < slRight.size(); k++) {
							if (q != (countPreponas.length -1))
								if ( ( (ip.getWidth() / 20 * q) <= (((slopes)slRight.get(k)).x1)) && ( (((slopes)slRight.get(k)).x1) < ( (ip.getWidth() / 20 * (q+1)) ) ) ){
									if (((slopes)slRight.get(k)).angle != 0) {
										averageSlope[q] = averageSlope[q] + ((slopes)slRight.get(k)).multi;
										countPreponas[q] = countPreponas[q] + ((slopes)slRight.get(k)).prepona;
									}
								}
						}
					}
					
					for (int k = 0; k < countPreponas.length; k++) {
						averageSlope[k] = averageSlope[k] / countPreponas[k];
						System.out.println("averageSlope[k] "+averageSlope[k]);
					}*/
					
					
					double averageSlope = 0;
					double countPreponas = 0;
					for (k = 0; k < slLeft.size(); k++) {
						//if (((slopes)slLeft.get(k)).angle != 0) {
							averageSlope = averageSlope + ((slopes)slLeft.get(k)).multi;
							countPreponas++;// = countPreponas + ((slopes)slLeft.get(k)).prepona;
						//}
					}
/*					for (k = 0; k < slRight.size(); k++) {
						if (((slopes)slRight.get(k)).angle != 0) {
							averageSlope = averageSlope + ((slopes)slRight.get(k)).multi;
							countPreponas = countPreponas + ((slopes)slRight.get(k)).prepona;
						}
					}*/
					
					averageSlope = averageSlope / countPreponas;
					//averageSlope = ((slopes)slLeft.get(0)).multi / ((slopes)slRight.get(0)).prepona;
					//for (int k = 0; k < averageSlope.length; k++) {
						System.out.println("averageSlope "+averageSlope);
					//}
					
					//SHIFTING
					int shift = 0;
					
/*					for (int q = 0; q < averageSlope.length; q++) {
						for (i = 0; i < list.size(); i++) {
							horRunLength hrl = ((horRunLength)(list.get(i)));
							if (q != (countPreponas.length -1))
								if ( ( (ip.getWidth() / 20 * q) <= (hrl.c1)) && ( hrl.c1 < ( (ip.getWidth() / 20 * (q+1))) ) ){
									shift = (int)(hrl.r * Math.tan(averageSlope[q]));
									hrl.c1 = hrl.c1 + shift;
									hrl.c2 = hrl.c2 + shift;
								}
						}
					}*/
					
					for (i = 0; i < list.size(); i++) {
						horRunLength hrl = ((horRunLength)(list.get(i)));
						shift = (int)(hrl.r * Math.tan(averageSlope));
					//	System.out.println("shift "+shift);
						hrl.c1 = hrl.c1 + shift;
						hrl.c2 = hrl.c2 + shift;
					}
					
					int minHrl = 34344;
				//	for (int u = 0; u < redJ.size(); u++) {

						for (i = 0; i < list.size(); i++) {
							horRunLength hrl = ((horRunLength)(list.get(i)));
							if (kk == 0) {
								if (hrl.r < (Integer)(redJ.get(kk)))  {
									if (hrl.c1 < minHrl)
										minHrl = hrl.c1;
								}
							} else if ((hrl.r < (Integer)(redJ.get(kk))) && (hrl.r > (Integer)(redJ.get(kk-1)))) {
								if (hrl.c1 < minHrl)
									minHrl = hrl.c1;
							}
						}
			
					//}
					//System.out.println("minHRL "+minHrl);
					
				//	for (int u = 0; u < redJ.size(); u++) {
					for (i = 0; i < list.size(); i++) {
							horRunLength hrl = ((horRunLength)(list.get(i)));
							hrl.c1 = hrl.c1  - (minHrl -5);
							hrl.c2 = hrl.c2  - (minHrl -5);
							for (k = 0; k < hrl.len; k++) {
								nip3.putPixelValue(hrl.c1 + k, hrl.r, 0);
							}
					}
					
					for (i = 0; i < list.size(); i++) {
						horRunLength hrl = ((horRunLength)(list.get(i)));
						int originc1 = hrl.c1;
						if ((!hrl.above.isEmpty()) && (!hrl.below.isEmpty())) {
							hrl.c1 = ( ((horRunLength)(list.get((Integer)(hrl.above.get(0))))).c1 +
									+ ((horRunLength)(list.get((Integer)(hrl.below.get(0))))).c1 ) /2;
						} else if ((hrl.above.isEmpty()) && (!hrl.below.isEmpty())) {
							hrl.c1 = ((horRunLength)(list.get((Integer)(hrl.below.get(0))))).c1;
						}  else if ((!hrl.above.isEmpty()) && (hrl.below.isEmpty())) {
							hrl.c1 = ((horRunLength)(list.get((Integer)(hrl.above.get(0))))).c1;
						}
						
					//	System.out.println("Math.abs(originc1 - hrl.c1) "+Math.abs(originc1 - hrl.c1));
						if (Math.abs(originc1 - hrl.c1) >= 2) {
							int min = originc1;
							int max = originc1;
							if ((!hrl.above.isEmpty()) && (!hrl.below.isEmpty())) {
								min = Math.min(((horRunLength)(list.get((Integer)(hrl.above.get(0))))).c1,  ((horRunLength)(list.get((Integer)(hrl.below.get(0))))).c1);
								max = Math.max(((horRunLength)(list.get((Integer)(hrl.above.get(0))))).c1,  ((horRunLength)(list.get((Integer)(hrl.below.get(0))))).c1);
							} else if ((hrl.above.isEmpty()) && (!hrl.below.isEmpty())) {
								min = ((horRunLength)(list.get((Integer)(hrl.below.get(0))))).c1;
								max = ((horRunLength)(list.get((Integer)(hrl.below.get(0))))).c1;
							}  else if ((!hrl.above.isEmpty()) && (hrl.below.isEmpty())) {
								min = ((horRunLength)(list.get((Integer)(hrl.above.get(0))))).c1;
								max = ((horRunLength)(list.get((Integer)(hrl.above.get(0))))).c1;
							}
							int minimum = min;
							for (k = min; k <= max; k++) {
								if (Math.abs(originc1 - k) < minimum)
									minimum = k;
							}
							//System.out.println("originc1 "+originc1);
							//System.out.println("minimum "+minimum);
							if (minimum >= 2)
								hrl.c1 = originc1;
							else 
								hrl.c1 = minimum;
						}
						
						
						int originc2 = hrl.c2;
						//System.out.println("originc2 "+originc2);
						if ((!hrl.above.isEmpty()) && (!hrl.below.isEmpty())) {
							hrl.c2 = ( ((horRunLength)(list.get((Integer)(hrl.above.get(hrl.above.size() - 1))))).c2 +
									+ ((horRunLength)(list.get((Integer)(hrl.below.get(hrl.below.size() - 1))))).c2 ) /2;
						} else if ((hrl.above.isEmpty()) && (!hrl.below.isEmpty())) {
							hrl.c2 = ((horRunLength)(list.get((Integer)(hrl.below.get(hrl.below.size() - 1))))).c2;
						}  else if ((!hrl.above.isEmpty()) && (hrl.below.isEmpty())) {
							hrl.c2 = ((horRunLength)(list.get((Integer)(hrl.above.get(hrl.above.size() - 1))))).c2;
						}
					//	System.out.println("hrl.c2 "+hrl.c2);
						
					//	System.out.println("Math.abs(originc2 - hrl.c2) "+Math.abs(originc2 - hrl.c2));
						if (Math.abs(originc2 - hrl.c2) >= 2) {
							int min = originc2;
							int max = originc2;
							if ((!hrl.above.isEmpty()) && (!hrl.below.isEmpty())) {
								min = Math.min(((horRunLength)(list.get((Integer)(hrl.above.get(hrl.above.size() - 1))))).c2,  ((horRunLength)(list.get((Integer)(hrl.below.get(hrl.below.size() - 1))))).c2);
								max = Math.max(((horRunLength)(list.get((Integer)(hrl.above.get(hrl.above.size() - 1))))).c2,  ((horRunLength)(list.get((Integer)(hrl.below.get(hrl.below.size() - 1))))).c2);
							} else if ((hrl.above.isEmpty()) && (!hrl.below.isEmpty())) {
								min = ((horRunLength)(list.get((Integer)(hrl.below.get(hrl.below.size() - 1))))).c2;
								max = ((horRunLength)(list.get((Integer)(hrl.below.get(hrl.below.size() - 1))))).c2;
							}  else if ((!hrl.above.isEmpty()) && (hrl.below.isEmpty())) {
								min = ((horRunLength)(list.get((Integer)(hrl.above.get(hrl.above.size() - 1))))).c2;
								max = ((horRunLength)(list.get((Integer)(hrl.above.get(hrl.above.size() - 1))))).c2;
							}
							int minimum = min;
							for (k = min; k <= max; k++) {
								if (Math.abs(originc2 - k) < minimum)
									minimum = k;
							}
					//		System.out.println("originc2 "+originc2);
					//		System.out.println("minimum "+minimum);
							if (minimum >= 2)
								hrl.c2 = originc2;
							else 
								hrl.c2 = minimum;
						//	System.out.println("hrl.c2 "+hrl.c2);
						}
						hrl.len = hrl.c2 - hrl.c1 +1;
					//	System.out.println("hrl.c1 "+hrl.c1);
					//	System.out.println("hrl.len "+hrl.len);
						
						for (k = 0; k < hrl.len; k++) {
							nip4.putPixelValue(hrl.c1 + k, hrl.r, 0);
						}
					}
					

			//////////////////////////////		
					
					
					for (k = 0; k < list.size(); k++) {
						randomColor = Color.getHSBColor( random.nextFloat(), 1.0F, 1.0F );
						color = ((randomColor.getRed() & 0xff) << 16) + ((randomColor.getGreen() & 0xff) << 8) + (randomColor.getBlue() & 0xff);
					//	for (int index = 0; index < left.get(k).size(); index++) {
							horRunLength hrl = ((horRunLength)(list.get(k)));
							//System.out.println(k+" "+index);
							nip2.putPixel(hrl.c1, hrl.r, color);
						//}
					}
					
					for (k = 0; k < right.size(); k++) {
						randomColor = Color.getHSBColor( random.nextFloat(), 1.0F, 1.0F );
						color = ((randomColor.getRed() & 0xff) << 16) + ((randomColor.getGreen() & 0xff) << 8) + (randomColor.getBlue() & 0xff);
						for (int index = 0; index < right.get(k).size(); index++) {
							horRunLength hrl = ((horRunLength)(right.get(k).get(index)));
							//System.out.println(k+" "+index);
							nip2.putPixel(hrl.c2, hrl.r, color);
						}
					}		

		}
/*		mainWindow.intFrame[FileChooser.number] = new internalFrame("Left and right contours", imp3, FileChooser.number);
		try {
			mainWindow.intFrame[FileChooser.number].setSelected(true);
		} catch(Exception e){
			System.out.println("Chyba");
		}	
		++FileChooser.number;*/
		
		mainWindow.intFrameArrayList.add(new internalFrame("Slant-angle Correction", 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;
		
		
		color = ((Color.red.getRed() & 0xff) << 16) + ((0 & 0xff) << 8) + (0 & 0xff);
		nip4.setColor(color);
		for (int i = 0; i < redJ.size(); i++) {
			nip4.drawLine(0, (Integer)(redJ.get(i)), nip4.getWidth(), (Integer)(redJ.get(i)));
		}
		
		mainWindow.intFrameArrayList.add(new internalFrame("Smoothing", imp5, 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;
	}
	
}

