package segmentation;

import java.awt.Color;
import java.util.ArrayList;

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

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

public class BaseLines {
	
	ImagePlus imp, impSeparLines, impSeparLines2, imp3;
	ImageProcessor ip, nip, nip2;
	int numberResult;
	boolean draw;
	boolean setSelected;
	
	public BaseLines(ImagePlus imp, ImageProcessor ip, ImagePlus impSeparLines, int numberResult, boolean draw, boolean setSelected) {
		this.imp = imp;
		this.ip = ip;
		this.impSeparLines = impSeparLines;
		this.numberResult = numberResult;
		this.setSelected =setSelected;
		this.draw = draw;
	}	
	
	public void run() {
		ImageProcessor ipOtsu = impSeparLines.getProcessor();
		
		ImagePlus impSeparLines2 = NewImage.createRGBImage ("Baselines detection", ipOtsu.getWidth(), ipOtsu.getHeight(), 1, NewImage.FILL_WHITE);		
		ImageProcessor ipOtsu2 = impSeparLines2.getProcessor();	
		
		for (int i = 0; i < impSeparLines.getWidth(); i++) {
			for (int j = 0; j < impSeparLines.getHeight(); j++) {
				if (ipOtsu.getPixelValue(i, j) == 0)
					ipOtsu2.putPixelValue(i, j, 0);
			}
		}
		
		int[] h = new int[ip.getHeight()];
		
		for (int j = 0; j < ip.getHeight(); j++) {
			int count = 0;
			for (int i = 0; i < ip.getWidth(); i++) {
				if (ip.getPixelValue(i, j)==0) count++;
			}
			h[j] = count;
			//System.out.println("h[j] "+h[j]);
		}
		
		////////////
		//result - height of handwriting////
		ImagePlus imp2 = NewImage.createRGBImage ("Baselines detection", ip.getWidth(), ip.getHeight(), 1, NewImage.FILL_WHITE);		
		nip = imp2.getProcessor();	
		
		for (int i = 0; i < ip.getWidth(); i++) {
			for (int j = 0; j < ip.getHeight(); j++) {			
				nip.putPixelValue(i, j, ip.getPixelValue(i, j));
			}
		}
		
		nip.setColor(Color.red);
		////
		//ImagePlus imp3 = NewImage.createRGBImage ("Baselines detection", ip.getWidth(), ip.getHeight(), 1, NewImage.FILL_WHITE);		
		imp3 = NewImage.createRGBImage ("Baselines detection", ipOtsu2.getWidth(), ipOtsu2.getHeight(), 1, NewImage.FILL_WHITE);
		
		nip2 = imp3.getProcessor();	

		
		for (int i = 0; i < ipOtsu2.getWidth(); i++) {
			for (int j = 0; j < ipOtsu2.getHeight(); j++) {			
				nip2.putPixelValue(i, j, ipOtsu2.getPixelValue(i, j));
			}
		}
		
		nip2.setColor(Color.red);
		
		ArrayList resHeight = new ArrayList();
		ArrayList start = new ArrayList();//-1;
		ArrayList end = new ArrayList();//-1;
		
		for (int i = 0; i < h.length; i++) {
			if (i != h.length -1) {
				if ((h[i] == 0) && (h[i+1] != 0) ) {
					start.add(i+1);
					nip.drawLine(0, i+1, nip.getWidth(), i+1);
					nip2.drawLine(0, i+1, nip.getWidth(), i+1);
				}
				if ((h[i] != 0) && (h[i+1] == 0) ) {
					end.add(i);
					nip.drawLine(0, i, nip.getWidth(), i);
					nip2.drawLine(0, i, nip.getWidth(), i);
				}
			}	
/*			if ((start != -1) && (end != -1)) {
				resHeight.add(end - start);
				end = -1;
				start = -1;
			}
*/		}
		
		for (int i = 0; i < start.size(); i++) {
			resHeight.add((Integer)(end.get(i)) - (Integer)(start.get(i)));
		}

		
		nip.setColor(Color.green);
		nip2.setColor(Color.green);

		double[] upperLine = new double[resHeight.size()];
		double[] lowerLine = new double[resHeight.size()];
		
		//najdi hornu a dolnu ciaru
		for (int k = 0; k < resHeight.size(); k++) {
			
			double[] aver = new double[(Integer)(resHeight.get(k))+1];
			for (int i = (Integer)(start.get(k)); i <= (Integer)(end.get(k)); i++) {
				if (i == (Integer)(start.get(k)))
					aver[i - (Integer)(start.get(k))] = h[i];
				else
					aver[i - (Integer)(start.get(k))] = aver[i-1-(Integer)(start.get(k))] + h[i];
				//System.out.println("aver["+(i- (Integer)(start.get(k)))+"] "+aver[i-(Integer)(start.get(k))]);
			}
			
			for (int i = 0; i < aver.length; i++) {
				aver[i] = aver[i] / (double)(i+1);
				//System.out.println("aver[i] "+aver[i]);
			}
			
			double[] diff = new double[aver.length - 1];
			for (int i = 0; i < diff.length; i++) {
				diff[i] = aver[i+1] - aver[i];
				//System.out.println("diff[i] "+diff[i]);
			}
			
			if (diff.length > 0) {
				double max = diff[0];
				int indexMax = 0;
				for (int i = 1; i < diff.length; i++) {
					if (diff[i] > max) {
						max = diff[i];
						indexMax = i + (Integer)(start.get(k));
					}
				}
	
				double min = 0;
				int indexMin = 0;
				for (int i = 1; i < diff.length; i++) {
					if ( (diff[i] < 0) && (min == 0) && (i > (indexMax - (Integer)(start.get(k)))) ) {
						min = diff[i];
						indexMin = i + (Integer)(start.get(k));
					}
				}
				
				upperLine[k] = indexMax;
				lowerLine[k] = indexMin;
				
				nip.drawLine(0, indexMax, nip.getWidth(), indexMax);
				nip2.drawLine(0, indexMax, nip.getWidth(), indexMax);
	
				nip.drawLine(0, indexMin, nip.getWidth(), indexMin);
				nip2.drawLine(0, indexMin, nip.getWidth(), indexMin);
				
			}
		}
		
		
		double[] resultHeight = new double[resHeight.size()];
		for (int i = 0; i < resultHeight.length; i++) {
			resultHeight[i] = (Integer)(resHeight.get(i));
			//resultHeight[i] = resultHeight[i] / (Result.getHeightTextLine() / 100);
			//System.out.println("HEIGHT[i] "+resultHeight[i]);
		}
		
		//pixle TODO zmenit na percentualnost
		Result.setHeightHandwr(resultHeight, numberResult);	
		
		//zmenim rozdiely medzi riadkami, tym ze od kazdeho riadku odpocitam dlzku pisma v riadku
		double[] resultDiffLines = new double[Result.getDiffLinesArray().length];
		resultDiffLines = Result.getDiffLinesArray();
		
		double[] resultDiffLinesNew = new double[resultDiffLines.length];
		
		for (int i = 0; i < resultDiffLinesNew.length; i++) {
			//if (i != resultHeight.length - 1)
			//System.out.println("DIFF LINES"+resultDiffLines[i]);
			if (i != resultHeight.length - 1)
				resultDiffLinesNew[i] = resultDiffLines[i] - resultHeight[i+1];
		}
		
		Result.setDiffLines(resultDiffLinesNew, numberResult);
		
		double[] element1 = new double[resHeight.size()];
		double[] element2 = new double[resHeight.size()];
		double[] element3 = new double[resHeight.size()];
		
		for (int i = 0; i < element1.length; i++) {
			element1[i] = upperLine[i] - (Integer)(start.get(i));
			element2[i] = lowerLine[i] - upperLine[i];
			element3[i] = (Integer)(end.get(i)) - lowerLine[i];
		}
		
		///zapis do resultu
		Result.setThreeElementsChar1(element1, numberResult);
		Result.setThreeElementsChar2(element2, numberResult);	
		Result.setThreeElementsChar3(element3, numberResult);	
		
		//ratio hodnoty
		//Ratios of elemenst: 1/2, 2/3, 1/3
		double[] ratio1 = new double[resHeight.size()];
		double[] ratio2 = new double[resHeight.size()];
		double[] ratio3 = new double[resHeight.size()];		
		
		for (int i = 0; i < ratio3.length; i++) {
/*			ratio1[i] = element1[i] / element2[i];
			ratio2[i] = element2[i] / element3[i];
			ratio3[i] = element1[i] / element3[i];*/
			double onePerc = ((double)(resultHeight[i]) / (double)(100));
			ratio1[i] = element1[i] / onePerc;
			ratio2[i] = element2[i] / onePerc;
			ratio3[i] = element3[i] / onePerc;
		}
		
		///zapis do resultu
		Result.setRatioThreeElementsChar1(ratio1, numberResult);
		Result.setRatioThreeElementsChar2(ratio2, numberResult);	
		Result.setRatioThreeElementsChar3(ratio3, numberResult);	
		
		//ratio lines/height
		//OPRAVITTTTTTT TODO
/*		double[] diffLines = new double[Result.getDiffLines().length];
		for (int i = 0; i < diffLines.length; i++) {
			diffLines[i] = Result.getDiffLines()[i];
		}
		double[] ratioLinesHeight = new double[diffLines.length];
		for (int i = 0; i < ratioLinesHeight.length; i++) {
			ratioLinesHeight[i] = diffLines[i] / resultHeight[i];
		}
		
		Result.setRatioLinesHeight(ratioLinesHeight, numberResult);*/
		
		if (draw) {
		
/*			mainWindow.intFrameArrayList.add(new internalFrame("Proportion", imp2, FileChooser.number, numberResult, 1, true));
			try {
				//mainWindow.intFrame[FileChooser.number].setSelected(true);
				((internalFrame)(mainWindow.intFrameArrayList.get(FileChooser.number))).setSelected(setSelected);
			} catch(Exception e){
				System.out.println("Chyba");
			}	
			++FileChooser.number;*/
			
			mainWindow.intFrameArrayList.add(new internalFrame("Proportion", imp3, FileChooser.number, numberResult, 1, true));
			try {
				//mainWindow.intFrame[FileChooser.number].setSelected(true);
				((internalFrame)(mainWindow.intFrameArrayList.get(FileChooser.number))).setSelected(setSelected);
			} catch(Exception e){
				System.out.println("Chyba");
			}	
			++FileChooser.number;	
		
		}
	}
	
	public ImagePlus getImg(){
		return imp3;
	}
	
	public ImageProcessor getIp(){
		return nip2;
	}	
	
	protected void finalize() throws Throwable {
	    try {
	        //close();        // close open files
	    } finally {
	        super.finalize();
	        System.out.println("baseline has been finalized.");
	    }
	}	

}

