import Comparator;

/**
 * Compares two objects by considering their values as integers.
 * The objects should be Integers or Numbers.
 *
 * @author Samuel A. Rebelsky
 * @version 1.0 of October 1999
 */
public class SimpleIntegerComparator
  implements Comparator
{
  // +-----------+-----------------------------------------------
  // | Constants |
  // +-----------+

  /** Used by compare to indicate the first param is smaller. */
  protected static final int SMALLER = -1;
  /** Used by compare to indicate the two params are equal. */
  protected static final int EQUAL = 0;
  /** Used by compare to indicate the first param is larger. */
  protected static final int LARGER = 1;

  /**
   * Determines if the integer corresponding to the first object 
   * is the same as the integer corresponding to the second object.
   * Pre: The two objects are initialized and can be converted to integers.
   * Post: Returns true if they are equal and false otherwise.
   *
   * @exception IncomparableException
   *   If either or both canot be converted to integers.
   */
  public boolean equals(Object first, Object second)
    throws IncomparableException
  {
    return (compare(first,second) == EQUAL);
  } // equals(Object,Object)

  /* Determines if the integer corresonding to the first object
   * is less than the integer corresponding to the second object.
   * Pre: The objects must be convertable to integers.
   * Post: Return true if the first precedes the second and
   *   false otherwise.
   *
   * @exception IncomparableException
   *   If either or both cannot be converted to integers.
   */
  public boolean lessThan(Object first, Object second)
    throws IncomparableException
  {
    return (compare(first,second) == SMALLER);
  } // lessThan(Object,Object)

  /**
   * Determine the relative value of two objects that should 
   * be Integers.
   * Pre: Both objects are Integers or Numbers.
   * Post: Returns SMALLER if the integer corresponding to the first is 
   *   smaller than the integer corresponding to the second.
   * Post: Returns EQUAL if those two values are the same.
   * Post: Returns LARGER if the first is greater than the second. 
   *
   * @exception IncomparableException 
   *   if either or both are not numbers.
   */
  protected int compare(Object first, Object second) 
    throws IncomparableException
  {
    // An error message.  Becomes something other than the
    // empty string if there is an error.
    String error = "";
    // The Numbers that correspond to the two parameters.
    // Initialized to keep Java happy.
    Number firstInt = null;
    Number secondInt = null;
    // Try to get the first integer.  Note that "(type) exp"
    // tells Java to try to treat "exp" as the given type.
    try { firstInt = (Number) first; }
    catch (Exception e) {
      error = error + "'" + first.toString() + "' is not a number. ";
      error = error + "It is in " + first.getClass().toString() + ". ";
    }
    // Try to get the second integer.
    try { secondInt = (Number) second; }
    catch (Exception e) {
      error = error + "'" + second.toString() + "' is not a number. ";
      error = error + "It is in " + first.getClass().toString() + ". ";
    }
    // If we've hit an error, tell the user.
    if (!error.equals("")) {
      throw new IncomparableException(error);
    }
    // Otherwise, do the normal comparison. 
    if (firstInt.intValue() < secondInt.intValue()) 
      return SMALLER;
    else if (firstInt.intValue() == secondInt.intValue()) 
      return EQUAL;
    else
      return LARGER;
  } // compare(Object,Object)
} // class SimpleIntegerComparator
