import java.io.*;
import java.util.*;

// Programmer: Erik Krohn
// Please report errors to Erik or the professor
// Date: 3-31-2006

public class SpellCheck {
	private Dictionary dict=new Dictionary(10501);

	public SpellCheck(){
		getWords();  //puts words in dictionary
		check(promptUser());  //prompts user for file name and does work
	}

	public void getWords(){
		try{
			BufferedReader fin = new BufferedReader(new FileReader("words.dat"));
			String word;
			while((word=fin.readLine())!=null){
				dict.insert(new Record(word));  //insert word into dictionary
			}
		} catch(Exception e){
			System.out.println(e);
		}
		//insert a and i into dictionary
		dict.insert(new Record("a"));
		dict.insert(new Record("i"));
	}

	//read in file names
	public String getInput(){
		try{
			BufferedReader fin = new BufferedReader(new InputStreamReader(System.in));
			return fin.readLine();
		} catch(Exception e){
			System.out.println(e);
		}
		return null;
	}

	//ask user for files
	public String promptUser(){
		System.out.print("Enter source file to spell check: ");
		return getInput();
	}

	public void check(String file){
		try{
			BufferedReader fin = new BufferedReader(new FileReader(file));
			PrintWriter fout = new PrintWriter(new FileWriter(file+".out"));
			String line;
			String word = "";
			String newLine = "";
			char ch;

			//Get each line of file
			while((line=fin.readLine())!=null){
				/***************
				 *  The basic algorithm for this is:
				 *    0.  Keep track of the newLine to print out
				 *    1.  Read in a character until you have a word.  Check if word is in the dictionary, if in the dictionary
				 *		  but needs a replacement, add replacement to newLine otherwise add work to newLine along with ch (to correspond to ' or , or . etc.)
				 *    2.  If word is not in dictionary.
				 *		  a.  replace - add replaced word to newLine
				 *		  b.  replaceAll - add replacement to dictionary with word (as a lower case) as the key
				 *		  c.  ignore - add original word to newLine
				 *		  d.  ignoreAll - add word to dictionary and add to newLine
				 *	  	  e.  abort - delete file and quit
				 *	  3.  Print off newLine and repeat until no new lines
				******************/
				for (int i = 0; i <= line.length(); i++)
				{
					ch = ' ';
					if(i < line.length())
						ch = line.charAt(i);

					// word is being constructed
					if (Character.isLetter(ch)){
						word = word + ch;
					}
					else if (word.length() != 0)
					{
						//word not found in dictionary as is, need to change to lowercase and search
						Record found = dict.search(word.toLowerCase());
						if (found != null)
						{
							if (found.replacement == null)
							{
								//add work to line
								newLine += word;
							}
							else
							{
								//add replacement to newline
								newLine += found.replacement;
							}
						}
						else
						{
							//word not in dictionary at all
							int redo = 0;
							while (redo == 0)
							{
								String x = alert(word).toLowerCase();
								if (x.length() > 0)
								{
									char toDo = x.charAt(0);
									redo = 1;  //only for incorrect input
									switch (toDo)
									{
										case 'r':
											//replace word
											System.out.print("Please enter a replacement > ");
											word = getInput();
											newLine += word; //replace wrong word 
											break;
										case 'i':
											//do nothing, simply ignoring word
											newLine += word;
											break;
										case 'n':
											//ignore all
											//add word to our dictionary
											Record temp = new Record(word.toLowerCase());
											dict.insert(temp);
											newLine += word;
											break;
										case 'a':
											//aborting
											fout.close();
											fin.close();
											new File(file + ".out").delete();
											System.out.println("Aborted");
											System.exit(0);
										case 'p':
											//replace all, add to dictionary
											String replace;
											System.out.print("Please enter a replacement > ");
											replace = getInput();
											temp = new Record(word.toLowerCase());
											temp.replacement = replace; //create a new record with word as the key
											dict.insert(temp);
											newLine += replace;
											break;
										default:
											System.out.println("Invalid input, please choose correctly!");
											redo = 0;
									}
								}
								else
									System.out.println("Invalid input, please choose correctly!");
							} // end of while-redo

						} // end of if-word-not-found
						//reset word and add character that followed the word
						word = "";
						if(i < line.length())
							newLine += ch;
					}
					else
					{
						//add character to newLine.  for example, "I went to the store, and bought a beverage."  
						//This is so we include the space after the comma
						if(i < line.length())
							newLine += ch;
					}
					
				}	
				//print off our line
				fout.print(newLine);
				fout.print("\n");
				newLine = "";
			}
			fout.close();
			fin.close();
		} catch(Exception e){
			System.out.println(e);
		}
	}

	public String alert(String word){
		//Offer options for unknown word
		System.out.println("\nThe word: \""+word+"\" is unknown.");
		System.out.print("Do you want to replace (R), replace all (P), ignore (I), ignore all (N), or abort (A)? > ");
		try{
			return getInput();
		}
		catch(Exception e){};
		return null;
	}

	public static void main(String[] args) {
		new SpellCheck();
	}
}
