
/**************************************************************************************************/
/*                                                                                                */
/*  Name:  DarC KonQuesT                                                                          */
/*  Program:  #3                                                                                  */
/*  Date:  2005.11.07                                                                             */
/*  Purpose:                                                                                      */
/*    Implementation file for SpellCheck class, reads dictionary and document into AVL Trees      */
/*     then compares to find mispelled words                                                      */
/*                                                                                                */
/*                                                                                                */
/**************************************************************************************************/

#include "SpellCheck.h"
#include <string>
#include <iomanip>


/*  Name:  readDictionaryFile()                                                                                       */
/*  Purpose:  read dictionary file into AVLtree                                                                       */
/*  Parameters:                                                                                                       */
/*  Preconditions: dictionary file exists, AVLTree dictionary intitialized                                            */
/*  Postconditions:  dictionary file input into AVLTree                                                               */

void SpellCheck::readDictionaryFile()
{
  
  const string dfile = "dictionary";
  fstream dstream;
  string word;
  dstream.open(dfile.c_str(), ios::in);
  while(dstream >> word)
  {
    dictionary.insert(word);
  }
}

/*  Name:  readDocumentFile()                                                                                         */
/*  Purpose:  read document file into an AVLTree                                                                      */
/*  Parameters:                                                                                                       */
/*  Preconditions: document file exists and AVLTree words initialized                                                 */
/*  Postconditions:  document words read into AVLTree                                                                 */

void SpellCheck::readDocumentFile()
{
  fstream docstream;
  string docfname, word;
  
  cout << endl << "Enter the name of the document file: ";
  cin >> docfname;
  docstream.open(docfname.c_str(), ios::in);
  while(docstream >> word)
  {
    string temp;
    for(unsigned i = 0; i < word.length(); i++)
      temp += (char)tolower(word[i]);
    word = temp;

    while(!isalpha(word[word.length()-1]))
      word.erase(word.length() -1);

    if(words.find(word) == words.end())
    {cout << "inerting : " << word << endl;
      words.insert(word);
    }
  }
  docstream.close();
}


/*  Name: compare()                                                                                                   */
/*  Purpose:  compare words in dictionary to document and output mispellings (check for basic errors)                 */
/*  Parameters:                                                                                                       */
/*  Preconditions: variables initialized, dictionary and words AVLTrees setup                                         */
/*  Postconditions: possible mispelled words output                                                                   */

void SpellCheck::compare()
{
  AVLTree< string, less< string > > :: Iterator itr;
  char t_char;
  char alphabet[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
  string temp;
  string s_char;
  bool prev_found;
  
  cout << "Possible misspelled words" << setw(33) << "Possible Alternatives" << endl;
  cout << "-----------------------------------------------------------" << endl;
  for(itr = words.begin(); itr != words.end(); itr++)
  {
    prev_found = false;
    if(dictionary.find(*itr) == dictionary.end())
    {
      cout << *itr;
//check for transpose
      temp = *itr;
      for(int i = 0; i <= temp.length(); i++)
      {
       t_char = temp[i];
       temp[i] = temp[i+1];
       temp[i+1] = t_char;
       if(dictionary.find(temp) != dictionary.end())
       {
         if(!prev_found)
          cout << setw(38);
         else if(prev_found)
          cout << ", ";
         cout << temp;
          t_char = temp[i];
          temp[i] = temp[i+1];
          temp[i+1] = t_char;
          prev_found = true;
       }
       else
       {
         t_char = temp[i];
         temp[i] = temp[i+1];
         temp[i+1] = t_char;
       }
      }

//check for single letter INSERTIONS
      temp = *itr;
      for(int k = 0; k <= temp.length(); k++)
      {
        for(int j = 0; j < 26; j++)
        {
          s_char = alphabet[j];
          temp.insert(k, s_char);
          if(dictionary.find(temp) != dictionary.end())
          {
            if(!prev_found)
              cout << setw(39);
            else if(prev_found)
              cout << ", ";
            cout << temp;
            temp.erase(k, 1);
            prev_found = true;
          }
          else
            temp.erase(k, 1);
        }
      }

//check for single letter REPLACEMENTS
      temp = *itr;
      for(int k = 0; k <= temp.length(); k++)
      {
        for(int j = 0; j < 26; j++)
        {
          t_char = temp[k];
          temp[k] = alphabet[j];
          if(dictionary.find(temp) != dictionary.end())
          {
            if(!prev_found)
              cout << setw(38);
            else if(prev_found)
              cout << ", ";
            cout << temp;
            temp[k] = t_char;
            prev_found = true;
          }
          else
            temp[k] = t_char;         
        }
                    
      }
                 
               
      cout << endl;
    }
  }
}



