
import java.awt.Font;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Comparator;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;


/**
 *
 * @author Bill Kraynek
 */
public class CountWordsWithWordClassUsingMaps {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        URL url = new URL("http://www.cis.fiu.edu/~kraynek/COP3337-examples/CountWordsWithWordClassUsingMaps.java");
        URLConnection connection = url.openConnection();
        Scanner fileScanner = new Scanner(connection.getInputStream());
        fileScanner.useDelimiter("[^A-Za-z]+");
        Map<String,WordClass> words = new TreeMap<String,WordClass>(new IgnoreCaseComparator());
        int maxWordLength = 35;
        while (fileScanner.hasNext()) {
            String word = fileScanner.next();
            if (!words.keySet().contains(word)) {
                words.put(word,new WordClass(word));
            }// end if
            words.get(word).incrementCount();
        }// end while
        display(words, maxWordLength);
        Map<String,WordClass> words1 = new TreeMap<String,WordClass>(new CountWordsComparator(words));
        words1.putAll(words);
        display(words1, maxWordLength);
        Set<WordClass> values = new TreeSet<WordClass>(words.values());
        display(values,maxWordLength);
        Set<WordClass> values1 = new TreeSet<WordClass>(new CountWordsComparatorA());
        values1.addAll(words.values());
        display(values1,maxWordLength);
        String[] allWords = words.keySet().toArray(new String[0]);
        while (true) {
            String aWord = (String)JOptionPane.showInputDialog(null, "Choose a word", "All words in file",
                    JOptionPane.PLAIN_MESSAGE, null, allWords, allWords[0]);
            if (aWord == null) {
                return;
            }// end if
            WordClass word = words.get(aWord);
            JOptionPane.showMessageDialog(null, word.getWord() + " appeared " + word.getCount()+ " time(s).");
        }// end while

    }

    static void display(Set<WordClass> words, int maxWordLength) {
        String blanks = "";
        for ( int i = 0; i < maxWordLength + 1; i++  ) blanks += " ";
        String out = "  Word" + blanks.substring(8) + "Count\n\n";
        for ( WordClass word : words ) {
            out += word.getWord() + blanks.substring(word.getWord().length()) + word.getCount() + "\n";
        }// end for
        JTextArea outArea = new JTextArea(out,40,40);
        outArea.setFont(new Font(Font.MONOSPACED,Font.PLAIN,15));
        JOptionPane.showMessageDialog(null, new JScrollPane(outArea));
    }

    static void display(Map<String,WordClass> words, int maxWordLength) {
        String blanks = "";
        for ( int i = 0; i < maxWordLength + 1; i++  ) blanks += " ";
        String out = "  Word" + blanks.substring(8) + "Count\n\n";
        for ( String word : words.keySet() ) {
            out += word + blanks.substring(word.length()) + words.get(word).getCount() + "\n";
        }// end for
        JTextArea outArea = new JTextArea(out,40,40);
        outArea.setFont(new Font(Font.MONOSPACED,Font.PLAIN,15));
        JOptionPane.showMessageDialog(null, new JScrollPane(outArea));
    }
}

class WordClass implements Comparable<WordClass> {

    private String word;
    private int count;

    public WordClass(String word) {
        this.word = word;
        count = 0;
    }

    public String getWord() {
        return word;
    }

    public int getCount() {
        return count;
    }

    public void incrementCount() {
        count++;
    }

    public boolean equals(Object rhs) {
        if (rhs == null) {
            return false;
        }
        if (!this.getClass().equals(rhs.getClass())) {
            return false;
        }
        WordClass that = (WordClass) rhs;
        return this.getWord().equals(that.getWord());
    }

    public int hashCode() {
        return word.hashCode();
    }

    public int compareTo(WordClass rhs) {
        return this.getWord().compareTo(rhs.getWord());
    }
}// end WordClass

class CountWordsComparator implements Comparator<String> {
    private Map<String,WordClass> words;
    public CountWordsComparator( Map<String,WordClass> words) {
        this.words = words;
    }// end constructor

    public int compare(String lhs, String rhs) {
        int countDifference = words.get(rhs).getCount() - words.get(lhs).getCount();
        if (countDifference != 0) {
            return countDifference;
        }
        return lhs.compareTo(rhs);
    }
}// end WordCountComparator

class CountWordsComparatorA implements Comparator<WordClass> {
    public int compare(WordClass lhs, WordClass rhs) {
        int countDifference = rhs.getCount() - lhs.getCount();
        if (countDifference != 0) {
            return countDifference;
        }
        return lhs.compareTo(rhs);
    }

}

class IgnoreCaseComparator implements Comparator<String> {
    public int compare(String lhs,String rhs) {
        return lhs.compareToIgnoreCase(rhs);
    }
}

