import java.util.*;

/** Object that can be notified when a StyledWord word changes. */
interface WordChangeListener {
  public void onWordChange(StyledWord w);
}

/**
 * Class that stores text along with a color in which to display it. Notifies a
 * list of listeners after any update.
 */
class StyledWord {
  private StringBuffer text  = new StringBuffer();
  private Color color = new Color("black");
  private List<WordChangeListener> listeners;
 
  public StyledWord() {
    listeners = new ArrayList<>();
  }

  public StyledWord(Collection<WordChangeListener> ls) {
    listeners = new ArrayList<>(ls);
  }

  public void addListener(WordChangeListener l) {
    listeners.add(l);
  }

  public void removeListener(WordChangeListener l) {
    listeners.remove(l);
  }

  public Color getColor() {
    return color;
  }

  public void setColor(Color c) {
    color = c;
  }

  public String getText() {
    return new String(text);
  }

  public void addLetter(char c, int position) { 
    text.insert(position,c); 
    afterWordChange();
  }

  public void deleteLetter(int position) { 
    text.delete(position,position+1); 
    afterWordChange();
  }

  private void afterWordChange() {
    for(WordChangeListener listener : listeners) {
      listener.onWordChange(this);
    }
  }
}


/** Removes any Qs that were added. */
class QRemover implements WordChangeListener {
  @Override
  public void onWordChange(StyledWord word) {
    removeQs(word);
  }

  public void removeQs(StyledWord word) {
    int i = word.getText().indexOf('Q');
    if (i != -1) {
      word.deleteLetter(i);  // NOTE: this will make another call to removeQs!
    }
  }
}

/** Changes the color of a word to red if it isn't found in the dictionary. */
class Spellchecker implements WordChangeListener {
  private Dictionary dictionary;

  public Spellchecker(String language) {
    dictionary = Dictionary.findDictionary(language);
  }

  @Override
  public void onWordChange(StyledWord word) {
    performSpellcheck(word);
  }

  public void performSpellcheck(StyledWord word) {
    if (dictionary.contains(word.getText())) {
      word.setColor(new Color("black"));
    } else {
      word.setColor(new Color("red"));
    }
  }
}

/** Maintains a count of how many times the word has been changed. */
class ChangeCounter implements WordChangeListener { 
  private int count = 0;

  @Override
  public void onWordChange(StyledWord word) {
    count++;
  }

  public int getCount() {
    return count;
  }
}

class Main {
  public static void main(String[] args) {
    StyledWord w = new StyledWord();
    w.addListener(new Spellchecker("English"));
    w.addListener(new QRemover());
    w.addListener(new ChangeCounter());
    // ... edit the word ...
  }
}