package bschecker.bluesheets;

import java.util.ArrayList;

import bschecker.reference.Settings;
import bschecker.util.ErrorList;
import bschecker.util.LogHelper;
import bschecker.util.PerformanceMonitor;
import bschecker.util.UtilityMethods;
import javafx.beans.property.ReadOnlyDoubleWrapper;
import opennlp.tools.parser.Parse;

/**
 * Defines abstract class for types of grammatical errors
 * @author tedpyne
 * @author JeremiahDeGreeff
 */
public abstract class Bluesheet {
	
	/**
	 * Finds errors of a specific type in a paragraph.
	 * @param line the paragraph in which to find errors
	 * @param parses a Parse array of each sentence of the line
	 * @return an ErrorList which for each Error references start token, end token, and, optionally, a note
	 */
	protected abstract ErrorList findErrors(String line, Parse[] parses);
	
	/**
	 * Finds all errors within the given text.
	 * All types included in {@code ERROR_LIST} which have a {@code CheckedWhenAnalyzed} value of {@code true} will be checked.
	 * Expects text to end with a new line character.
	 * @param text the text to search
	 * @param logParses if true, all Parse trees will be logged to the console - should only be used for debugging
	 * @return a ErrorList which contains all the errors in the passage, referenced by character indices
	 */
	public static ErrorList findAllErrors(String text, boolean logParses, ReadOnlyDoubleWrapper progress) {
		PerformanceMonitor.start("analyze");
		if(!text.endsWith("\n"))
			text += "\n";
		ErrorList errors = new ErrorList(text, false);
		int lineNum = 1, charOffset = 0, totalLines = 0;
		String temp = text;
		while(temp.contains("\n")) {
			temp = temp.substring(temp.indexOf('\n') + 1);
			totalLines++;
		}
		String line;
		while (charOffset < text.length()) {
			PerformanceMonitor.start("line");
			if(progress != null) {
				System.out.println((double) lineNum / totalLines);
				progress.set((double) lineNum / totalLines);
			}
			line = text.substring(charOffset, charOffset + text.substring(charOffset).indexOf('\n'));
			LogHelper.line();
			LogHelper.getLogger(17).info("Analyzing line " + lineNum + " (characters " + charOffset + "-" + (charOffset + line.length()) + "):");
			ArrayList<Integer> removedChars = new ArrayList<Integer>();
			line = UtilityMethods.removeExtraPunctuation(line, charOffset, removedChars);
			LogHelper.getLogger(17).info("Ignoring characters: " + removedChars);
			
			PerformanceMonitor.start("parse");
			LogHelper.getLogger(18).info("Parsing line " + lineNum + "...");
			String[] sentences = UtilityMethods.separateSentences(line);
			Parse[] parses = new Parse[sentences.length];
			for(int i = 0; i < sentences.length; i++)
				parses[i] = UtilityMethods.parse(sentences[i], logParses);
			LogHelper.getLogger(18).info("Complete (" + PerformanceMonitor.stop("parse") + ")");
			
			ErrorList lineErrors = new ErrorList(line, true);
			for(Bluesheets b : Bluesheets.values())
				if(Settings.isSetToAnalyze(b.getNumber())) {
					PerformanceMonitor.start("bluesheet");
					LogHelper.getLogger(17).info("Looking for: " + b.getName() + "...");
					ErrorList bluesheetErrors = b.getObject().findErrors(line, parses);
					bluesheetErrors.setBluesheetNumber(b.getNumber());
					lineErrors.addAll(bluesheetErrors);
					LogHelper.getLogger(17).info(bluesheetErrors.size() + " Error" + (bluesheetErrors.size() == 1 ? "" : "s") + " Found (" + PerformanceMonitor.stop("bluesheet") + ")");
				}
			LogHelper.getLogger(17).info(lineErrors.size() + " Error" + (lineErrors.size() == 1 ? "" : "s") + " Found in line " + lineNum + " (" + PerformanceMonitor.stop("line") + ")");
			
			errors.addAll(lineErrors.tokensToChars(charOffset, removedChars));
			
			lineNum++;
			charOffset += line.length() + removedChars.size() + 1;
		}
		LogHelper.line();
		LogHelper.getLogger(17).info("Passage analyzed in " + PerformanceMonitor.stop("analyze") + "\n\n" + errors);
		
		return errors;
	}
	
}

@@ -1837,65 +1837,8 @@
 ull)
- %7B%0A%09%09%09%09System.out.println((double) lineNum / totalLines);
 %0A%09%09%09
@@ -1883,21 +1883,16 @@
 Lines);%0A
-%09%09%09%7D%0A
 %09%09%09line 

remove debugging