import java.util.Comparator;
import java.util.Scanner;

/**
 * Prompts the user for two words and orders them by length and according to colexical 
 * order. Illustrates runtime polymorphism with interfaces. See comments on lines 59-61.
 *
 * @author Drue Coles
 */
public class PolyDemo {


    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);
        System.out.print("Enter two words: ");
        String w1 = in.next();
        String w2 = in.next();

        class LengthComparator implements Comparator<String> {
            /**
             * Returns a negative or positive integer depending on whether s is shorter
             * or longer than t respectively. Strings of the same length are treated as
             * identical, so in this case zero is returned.
             */
            @Override
            public int compare(String s, String t) {
                return s.length() - t.length();
            }
        }

        class ColexicalComparator implements Comparator<String> {
            /**
             * Returns a negative or positive integer depending on whether s or t comes
             * first in colexical order. Colexical order is the same as lexical order
             * except that characters are compared from right to left. Returns zero if
             * s and t are the same.
             */
            @Override
            public int compare(String s, String t) {
                return t.compareTo(s);
            }
        }

        System.out.println("Length order: " + order(w1, w2, new LengthComparator()));
        System.out.println("Colexical order: " + order(w1, w2, new ColexicalComparator()));
    }

    /**
     * Returns a string expressing the order of two given strings x and y as determined by
     * a given comparator.
     */
    private static String order(String x, String y, Comparator<String> comparator) {

        // The call to compare cannot be bound at compile time. At runtime, the JVM
        // selects the appropriate method to execute depending on the type of
        // comparator (LengthComparator or ColexicalComparator).
        int result = comparator.compare(x, y);

        if (result < 0) {
            return x + " < " + y;
        }
        if (result > 0) {
            return x + " > " + y;
        }
        return x + " = " + y;
    }
}