import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Comparator;
import java.util.Scanner;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

/**
 * This Example illustrates a SortedLinkedList class
 * @author Bill Kraynek
 */
public class SortedLinkedListExample {
    
    public SortedLinkedListExample() {
        try{
            Scanner in = new Scanner(new File("src/SortedLinkedListExample.java"));
            in.useDelimiter("[^a-zA-Z]+");
            String file = "";
            while( in.hasNext() ) {
                file += in.next() + " ";
            } // end while
            List<String> words = getWordsSorted(file);
            displayList(words,"Natural Order");
            words = getWordsSorted(file,new IgnoreCaseComparator());
            displayList(words,"Ignore Case Order");
            words = getWordsSorted(file,new NaturalCompare<String>());
            displayList(words,"Natural Order");
            words = getWordsSorted(file,new CompareByLength());
            displayList(words,"Length Order");
            ListIterator<String> itr = words.listIterator();
            itr.next();
            itr.set("First");
            displayList(words,"After setting first element to First");
            itr.remove();
            displayList(words,"After removing the result of the set method");
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * Parse the String file for 'words' and store unique words in the List words
     * in sorted order
     * @param file is the String
     * @ @return the List of sorted words
     */
    public List<String> getWordsSorted(String file) {
        List<String> words = new SortedLinkedList<String>();
        Scanner parser = new Scanner(file);
        while( parser.hasNext() ) {
            String nextWord = parser.next();
            words.add(nextWord);
        } // end while
        return words;
    } // end getWordsSorted
    
    /**
     * Parse the String file for 'words' and store unique words
     * in the List words in sorted order using a Comparator<String>
     * @param file is the String
     * @param comparator is the Comparator<String>
     * @return the List of sorted words
     */
    public List<String> getWordsSorted(String file, Comparator<String> comparator) {
        List<String> words = new SortedLinkedList<String>(comparator);
        Scanner parser = new Scanner(file);
        while( parser.hasNext() ) {
            String nextWord = parser.next();
            words.add(nextWord);
        } // end while
        return words;
    } // end getWordsSorted
    
    /**
     * Display a List in a JTextArea
     * @param l is the List to display
     * @param title is a title for the display
     */
    public void displayList(List aList, String title) {
        Iterator itr = aList.iterator();
        String out = title + "\n\n";
        while( itr.hasNext() ) {
            out += "   " + itr.next() + "\n";
        }
        JTextArea outArea = new JTextArea(25,40);
        outArea.setText(out);
        JOptionPane.showMessageDialog(null,new JScrollPane(outArea));
    }// end display
    
    private class IgnoreCaseComparator implements Comparator<String> {
        public int compare(String a, String b) {
            return a.compareToIgnoreCase(b);
        }// end compare
    }// end IgnoreCaseComparator
    
    
    class CompareByLength implements Comparator<String> {
        public int compare(String left, String right) {
            int leftLength = left.length();
            int rightLength = right.length();
            if( leftLength != rightLength ) {
                return rightLength - leftLength;
            } else {
                return left.compareTo(right);
            } // end if
        } // end compare
    } // end CompareByLength
    
    class NaturalCompare<T extends Comparable<T>> implements Comparator<T> {
        public int compare(T left, T right) {
            return left.compareTo(right);
        } // end compare
    } // end NaturalCompare
    
    public static void main(String args[]) throws IOException {
        new SortedLinkedListExample();
        System.exit(0);
    } // end main
    
} // end SortedLinkedListExample


