// Purpose.  Template Method design pattern lab
//
// Problem.  2 different spell-checking objects have a lot of common
// functionality.  This means there is: lots of duplicate code, no reuse,
// and a maintenance nightmare if changes common to both classes become
// necessary.
//
// Assignment.
// o Create a common base class SpellChecker
// o Subclass SimpleSpellChecker and SophisticatedSpellChecker off of it
// o Move all common functionality to the base class
// o Wherever differences exist (i.e. bubbleSortTheInput(),
//   diffWithUnixDictionary(), proposeCorrectSpellings()), specify
//   "placeholders" in base class
// o Implement differences in concrete derived classes
//
// Hints.
// o "Placeholders" could be pure virtual member functions
// o "Placeholders" could be virtual member functions that are overridden
//   in the derived class, but "called back to" in the derived
//   implementation
// o If you have:
//     SimpleSomething::doItSimple() { cout << "doItSimple"; }
//     HardSomething::doItHard()     { cout << "doItHard"; }
// Consider creating something of the form:
//     Something::doIt() = 0;
//     SimpleSomething::doIt() { cout << "doItSimple"; }
//     HardSomething::doIt()   { cout << "doItHard"; }

#include <iostream.h>

class SimpleSpellChecker {
public:
   void doIt() {
      removeControlCodes();
      convertToLowerCase();
      tokenizeInput();
      bubbleSortTheInput();
      collapseDuplicateEntries();
      diffWithUnixDictionary();
      proposeCorrectSpellings();
   }
private:
   void removeControlCodes() {
      cout << "removeControlCodes:" << endl; }
   void convertToLowerCase() {
      cout << "convertToLowerCase:" << endl; }
   void tokenizeInput() {
      cout << "tokenizeInput:" << endl; }
   void bubbleSortTheInput() {
      cout << "bubbleSortTheInput:" << endl; }
   void collapseDuplicateEntries() {
      cout << "collapseDuplicateEntries:" << endl; }
   void diffWithUnixDictionary() {
      cout << "diffWithUnixDictionary:" << endl; }
   void proposeCorrectSpellings() {
      cout << "proposeCorrectSpellings:" << endl;
      cout << "   convert token to phonetic spelling" << endl;
      cout << "   generate all permutations" << endl;
      cout << "   use eenie-meenie to pick the best choices" << endl;
   }
};


class SophisticatedSpellChecker {
public:
   void doIt() {
      removeControlCodes();
      convertToLowerCase();
      tokenizeInput();
      mergeSortTheInput();
      collapseDuplicateEntries();
      diffWithOxfordDictionary();
      proposeCorrectSpellings();
   }
private:
   void removeControlCodes() {
      cout << "removeControlCodes:" << endl; }
   void convertToLowerCase() {
      cout << "convertToLowerCase:" << endl; }
   void tokenizeInput() {
      cout << "tokenizeInput:" << endl; }
   void mergeSortTheInput() {
      cout << "mergeSortTheInput:" << endl; }
   void collapseDuplicateEntries() {
      cout << "collapseDuplicateEntries:" << endl; }
   void diffWithOxfordDictionary() {
      cout << "diffWithOxfordDictionary:" << endl; }
   void proposeCorrectSpellings() {
      cout << "proposeCorrectSpellings:" << endl;
      cout << "   convert token to phonetic spelling" << endl;
      cout << "   generate all permutations" << endl;
      cout << "   rank order the permutations" << endl;
      cout << "   use AI to pick the best choices" << endl;
   }
};

void main( void ) {
   SimpleSpellChecker         okay;
   SophisticatedSpellChecker  good;
   cout << "********** Simple Spell Check **********" << endl;
   okay.doIt();
   cout << "********** Sophisticated Spell Check **********" << endl;
   good.doIt();
}

// ********** Simple Spell Check **********
// removeControlCodes:
// convertToLowerCase:
// tokenizeInput:
// bubbleSortTheInput:
// collapseDuplicateEntries:
// diffWithUnixDictionary:
// proposeCorrectSpellings:
//    convert token to phonetic spelling
//    generate all permutations
//    use eenie-meenie to pick the best choices
// ********** Sophisticated Spell Check **********
// removeControlCodes:
// convertToLowerCase:
// tokenizeInput:
// mergeSortTheInput:
// collapseDuplicateEntries:
// diffWithOxfordDictionary:
// proposeCorrectSpellings:
//    convert token to phonetic spelling
//    generate all permutations
//    rank order the permutations
//    use AI to pick the best choices